WPF Prism 对话框窗口 - 绑定到 DialogWindow 的宽度和高度

Posted

技术标签:

【中文标题】WPF Prism 对话框窗口 - 绑定到 DialogWindow 的宽度和高度【英文标题】:WPF Prism Dialog Window - Binding to the DialogWindow's Width and Height 【发布时间】:2021-06-05 05:00:38 【问题描述】:

我正在尝试保存 Prism WPF 对话框的宽度和高度,以便在下次使用该对话框时检索。

我有一个被序列化为 xml 以保存属性的静态类,因此我尝试通过将其注入构造函数并将其链接到 WindowWidth 和 WindowHeight 属性并将其绑定到 UserControl 后面的代码中,并使用绑定到xaml 中的命名元素如下所示:

用户控件 xaml:

    <UserControl
     x:Class="MyNameSpace.Views.MyView"
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:behaviors="clr-namespace:Microdesk.BIMrxCommon.WpfUi.Behaviors;assembly=Microdesk.BIMrxCommon.WpfUi"
     xmlns:core="clr-namespace:System;assembly=mscorlib"
     xmlns:data="clr-namespace:System.Data;assembly=System.Data"
     xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
     xmlns:mvvm="http://prismlibrary.com/"
     x:Name="MyViewControl"
     mvvm:ViewModelLocator.AutoWireViewModel="True">
    
        <mvvm:Dialog.WindowStyle>
            <Style TargetType="Window">
                <Setter Property="mvvm:Dialog.WindowStartupLocation" Value="CenterScreen" />
                <Setter Property="ResizeMode" Value="CanResizeWithGrip" />
                <Setter Property="ShowInTaskbar" Value="False" />
                <Setter Property="SizeToContent" Value="Manual" />
                <Setter Property="Height" Value="Binding WindowHeight, Mode=TwoWay, ElementName=MyViewControl, UpdateSourceTrigger=PropertyChanged" />
                <Setter Property="Width" Value="Binding WindowWidth, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ElementName=MyViewControl" />
    
            </Style>
    
        </mvvm:Dialog.WindowStyle>
....

后面的代码:

    public partial class MyView : UserControl    

        public IApplicationSettings ApplicationSettings  get; set; \\Injected in ctor

        public double WindowHeight
        
            get => ApplicationSettings.MyViewHeight;
            set => ApplicationSettings.MyViewHeight = value;
        

        public double WindowWidth        
            get => ApplicationSettings.MyViewWidth;
            set => ApplicationSettings.MyViewWidth = value;
        
...

但是绑定没有找到命名的 UserControl,而是试图在 DialogWindow 对象中找到属性:

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'ElementName=MyViewControl'. BindingExpression:Path=WindowHeight; DataItem=null; target element is 'DialogWindow' (Name=''); target property is 'Height' (type 'Double')

首先不确定这是否是正确的方法,感谢任何帮助。

更新:

我尝试将 WindowWidth 和 WindowHeight 属性添加到 ViewModel 而不是后面的代码。输出窗口没有显示任何关于绑定的抱怨,所以应该没问题,但是,在运行时更改窗口大小不会在视图模型中设置这些属性,就像实际窗口的宽度和高度是与我在 xaml 中绑定的那些。

【问题讨论】:

【参考方案1】:

您需要像这样将 UserControl 的 DataContext 设置为自身:

<UserControl
 x:Class="MyNameSpace.Views.MyView"
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:behaviors="clr-namespace:Microdesk.BIMrxCommon.WpfUi.Behaviors;assembly=Microdesk.BIMrxCommon.WpfUi"
 xmlns:core="clr-namespace:System;assembly=mscorlib"
 xmlns:data="clr-namespace:System.Data;assembly=System.Data"
 xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
 xmlns:mvvm="http://prismlibrary.com/"
 x:Name="MyViewControl"
 mvvm:ViewModelLocator.AutoWireViewModel="True"
 DataContext="Binding RelativeSource=RelativeSource Self">

然后就写

<Style TargetType="Window">
            <Setter Property="mvvm:Dialog.WindowStartupLocation" Value="CenterScreen" />
            <Setter Property="ResizeMode" Value="CanResizeWithGrip" />
            <Setter Property="ShowInTaskbar" Value="False" />
            <Setter Property="SizeToContent" Value="Manual" />
            <Setter Property="Height" Value="Binding WindowHeight" />
            <Setter Property="Width" Value="Binding WindowWidth" />

        </Style>

【讨论】:

虽然这可能适用于 OOTB WPF 应用程序,但它不适用于 Prism,正如您在我的代码中看到的那样,DataContext 由 ViewModelLocator 提供。如果我更改了 DataContext prism 会抱怨:System.NullReferenceException: 'A dialog's ViewModel must implement the IDialogAware interface'【参考方案2】:

事实证明,绑定到视图模型中的属性而不是问题更新中描述的代码背后的工作。 当我第一次尝试它时它不起作用的原因是我注册了一个自定义对话框窗口,并且该窗口在 xaml 中硬编码了高度和宽度,因此它没有响应绑定。 我刚刚删除了硬编码值,现在绑定可以工作了。

【讨论】:

以上是关于WPF Prism 对话框窗口 - 绑定到 DialogWindow 的宽度和高度的主要内容,如果未能解决你的问题,请参考以下文章

使用 Prism 和 MVVM 模式在 WPF 中创建模态对话框的“漂亮”方式

WPF Prism框架下基于MVVM模式的命令绑定事件

在 WPF 中并通过使用 Prism,如何使用 MouseButtonEventArgs 作为窗口命令的参数?

WPF MVVM 对话框示例

Prism For WPF Login对话框又简单又合理的方案之一

如何在 Prism 中为我的对话窗口设置区域管理器?