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

本文关键字:窗口 WPF ViewModel 新调整 调整 | 更新日期: 2023-09-27 17:52:54

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

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

我想要能够做的是,在ViewModel上设置一个依赖属性,并根据属性的值重新调整弹出窗口的宽度。因此,如果用户单击一个按钮,我可以使用ViewModel将弹出窗口的宽度加倍,并"展开"窗口以显示所有结果。如果用户随后单击收缩,则返回到原始宽度。

我可以重新调整窗口内的所有内容,但由于我以编程方式创建弹出窗口的方式,我无法弄清楚如何将弹出窗口的宽度链接到内容中包含的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用户控件。所以我在上面的弹出式服务中所做的就是以编程方式创建一个窗口,将内容设置为StackPanel,只有一个孩子,ResultViewer用户控件,其DataContext设置为ViewModel。然后我在窗口上设置了一些属性,如宽度,边距,显示在任务栏等,然后显示弹出窗口。

你可以看到在上面的例子中,我目前硬编码窗口的宽度属性为扩展的大小,只是为了测试。但我想这个宽度属性,而不是采取它的值从ViewModel的依赖属性,我已经创建了名为ScreenWidth。当我更新该属性时,我希望窗口相应地调整大小。

我怎样才能做到这一点?

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

Width = new Binding(...) 

但我不确定我是否能达到这个结果,或者我该怎么做。

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

有谁能给我提些建议吗?更新:

我已经在我的服务

上面的窗口对象创建中添加了以下行
DataContext = viewModel

所以窗口本身有它的数据上下文设置为VM,而不仅仅是ResultViewer用户控件。然后,我在窗口对象创建之后添加了以下行:

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

这个几乎可以工作。当我打开弹出窗口时,窗口最初以正确的大小加载,如果我单击展开,所有内容都会调整大小,但窗口本身不会。但是,如果您关闭弹出窗口并立即重新打开它,它将以扩展的大小出现。所以它似乎是拾取依赖属性很好,但只在窗口创建。如果你在弹出窗口打开的时候更新了依赖属性,它不会得到一些改变的通知,也不会动态地改变宽度。我正在调用RaisePropertyNotification根据需要和用户控件实时更新,所以属性通知是工作的,它只是不工作从父窗口宽度的角度来看。

还有什么我需要做的是连接INotifyPropertyChanged到我以编程方式创建的窗口绑定?

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

首先,您可以使用VisualStudio创建新窗口(例如:添加->新建项目->窗口(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;
...

我建议您在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();