从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到我以编程方式创建的窗口绑定?
首先,您可以使用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();