从ViewModel重新调整WPF中的弹出窗口大小

时间:2014-03-25 11:41:56

标签: c# wpf mvvm viewmodel

有点复杂。我正在使用WPF MVVM,我需要在网格中显示结果,然后当你双击它时,它会将结果加载到一个单独的弹出窗口中。

为此,我创建了一个 ResultViewerService ,它将 ViewModel 作为参数,用作此弹出窗口的内容,以及在窗口关闭时调用的回调。

我希望能够做的是在ViewModel上设置依赖项属性,并根据属性的值重新调整弹出窗口宽度。因此,如果用户单击按钮,我可以使用 ViewModel 将弹出窗口的宽度加倍,并向侧面“展开”窗口以显示所有结果。如果用户然后单击合同,则返回原始宽度。

我可以重新调整窗口中的所有内容,但由于我以编程方式创建弹出窗口的方式,我无法弄清楚如何将弹出窗口的 Width 链接到内容中包含的 ViewModel 上的属性。

我的弹出式创建服务方法如下

 public static Window OpenNew(ResultsViewModel viewModel, ResultsMainViewModel.CallbackResult callback)
        {
            var resultViewer = new ResultViewer(callback) { DataContext = viewModel };

            var panel = new StackPanel { Margin = new Thickness(0), Name = "ParentPanel" };
            panel.Children.Add(resultViewer);

            var win = new Window
                          {
                              Owner = Application.Current.MainWindow,
                              WindowStyle = WindowStyle.ToolWindow,
                              WindowStartupLocation = WindowStartupLocation.CenterOwner,
                              Opacity = 1,
                              ShowInTaskbar = false,
                              ResizeMode = ResizeMode.NoResize,
                              Height = 690,
                              Width = ResultsConstants.ResultsWidthExpanded,
                              Margin = new Thickness(0),
                              Padding = new Thickness(0),
                              Content = panel,
                              Topmost = false,
                              Background =
                                  new ImageBrush
                                      {
                                          ImageSource =
                                              new BitmapImage(new Uri(@"pack://application:,,,/WealthMarginAnalyser;component/Resources/Background2.jpg", UriKind.Absolute))
                                      }
                          };

            win.Closed += resultViewer.ResultViewer_Closed;
            win.Show();

            return win;
        }

ResultViewer 类是我用于弹出内容的XAML用户控件。所以我在上面的弹出服务中所做的就是以编程方式创建一个 Window ,将内容设置为只有一个子项的 StackPanel ResultViewer 将DataContext设置为 ViewModel 的用户控件。然后我以编程方式在窗口上设置了许多属性,如宽度,边距,任务栏中的显示等,然后显示弹出窗口。

您可以在上面的示例中看到我目前正在将窗口的Width属性硬编码为Expanded size,仅用于测试。但我希望这个Width属性从我创建的名为 ScreenWidth 的ViewModel依赖项属性中获取它的值。当我更新该属性时,我希望窗口相应地调整大小。

我怎样才能做到这一点?

我过去曾尝试手动创建 Bindings ,例如

Width = new Binding(...) 

但是我不确定我是否可以通过这种方式实现这一结果或者我将如何实现这一目标。

另一种方式是从ViewModel,以某种方式获得对弹出窗口的引用作为对象(当然不是纯MVVM)并手动设置宽度。

有人可以帮我提出建议吗?

更新:

我已将以下行添加到我上面的服务

中的Window对象创建中
DataContext = viewModel

因此窗口本身将其datacontext设置为 VM ,而不仅仅是ResultViewer用户控件。然后我在创建窗口对象后添加了以下行。

win.SetBinding(FrameworkElement.WidthProperty, new Binding("ScreenWidth"));

几乎有效。当我打开弹出窗口时,窗口最初以正确的大小加载,如果我单击展开,则所有内容都会调整大小,但窗口本身不会。如果你关闭弹出窗口然后立即重新打开它,它会以扩展的大小出现。所以它似乎正在接受依赖属性,但仅限于窗口创建。如果在弹出窗口打开时更新依赖项属性,则不会获得某些内容已更改的通知并动态更改宽度。我根据需要调用 RaisePropertyNotification 并且用户控件实时更新,因此属性通知正在工作,它从父窗口宽度的角度来看不起作用。

我还需要做些什么来将INotifyPropertyChanged连接到我以编程方式创建的Windows绑定吗?

2 个答案:

答案 0 :(得分:2)

首先,您可以使用VisualStudio创建新窗口(例如Add-> New Item-> Window(WPF))。 在此之后,您可以在XAML中设置窗口的所有属性:

Width="{Binding Path=MyWidth, Mode=TwoWay}" ShowInTaskbar = "False", ...

然后你可以实例化你的窗口并给它数据上下文:

....
var window = new MyWindow();
window.DataContext = MyViewModel;
win.Closed += resultViewer.ResultViewer_Closed;
win.Show();
return win;
...

希望得到这个帮助。

答案 1 :(得分:0)

我建议你在XAML中完成所有这些工作。创建一个ResultsWindow,将其DataContext分配给视图模型,并添加您需要的任何绑定。例如:

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        x:Class="MyApp.ResultsWindow"
        Height="{Binding WindowHeight}" 
        WindowStyle="ToolWindow"
        Background="...">
    <ResultViewer />
</Window>

然后在代码中:

var win = new ResultsWindow { DataContext = viewModel };
win.Show();