将视图DialogResult绑定到ViewModels属性



我对WPF、XAML和数据绑定相对陌生。我有一个视图(Window)和一个视图模型。

我已经尝试实现MVVM模式,这意味着视图和视图模型都没有相互引用。所有数据交换都通过数据绑定进行。

到目前为止还不错,但现在我遇到了一个我找不到解决方案的问题。

在我的视图中,我有一个绑定到命令的"开始"按钮。

<Button Command="{Binding NextCommand}" Content="Next">

NextCommand属于ActionCommand : ICommand 类型

在我的例子中,NextCommand只是在视图模型中调用一个私有方法。

到目前为止,我找不到解决方案的问题如下:

如何关闭视图模型末尾的窗口NextCommandAction方法?

private void NextCommandAction(object o)
{
    ...
    ...
    // close the window
}

由于我没有对视图的引用,我不能只设置DialogResult = true;

到目前为止,我找到的唯一可行的解决方案是向视图中添加一个隐藏的单选按钮,并将其值绑定到属性CloseView,然后在xaml.cs文件中创建一个方法CloseView,该文件绑定到隐藏单选按钮的Checked事件。在该方法中,我将DialogResult设置为true;

虽然这很有效,但我觉得必须有一个比在视图中添加隐藏元素更好的解决方案!

您可以将窗口引用作为CommandParameter传递给Close命令,并在窗口上执行任何需要的操作。

<Button Content="Close" Command="{Binding Path=CloseCommand}" 
  CommandParameter="{Binding ElementName=Window}"/>
private void CloseCommand(object sender)
{
    Window wnd = sender as Window;
    wnd.Close();
}

CommandParameter="{Binding ElementName=Window}"假设XAML中有一个名为"Window"的元素。例如,您的Window标签需要Name="Window"

当我在谷歌上搜索DialogResult是否是依赖属性(它不是:-))时,首先出现了这个问题

将依赖属性添加到您的窗口:

 public static readonly DependencyProperty InteractionResultProperty =
            DependencyProperty.Register(
                nameof(InteractionResult),
                typeof(Boolean?),
                typeof(MyWpfWindow1),
                new FrameworkPropertyMetadata(default(Boolean?), 
                    FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
                    OnInteractionResultChanged));
  public Boolean? InteractionResult
        {
            get => (Boolean?) GetValue(InteractionResultProperty);
            set => SetValue(InteractionResultProperty, value);
        }
        private static void OnInteractionResultChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((MyWpfWindow1) d).DialogResult = e.NewValue as Boolean?;
        }

我将我的属性命名为InteractionResult,尽管一个好的名称也会起作用。

在xaml中您可以将其与样式绑定


 <Window.Style>
        <Style TargetType="{x:Type z:MyWpfWindow1}">
            <Setter Property="InteractionResult"
                    Value="{Binding UpdateResult}" />
        </Style>
    </Window.Style>

UpdateResult是我的视图模型中的属性。

  private Boolean? _updateResult;
        public Boolean? UpdateResult
        {
            get => _updateResult;
            set => SetValue(ref _updateResult, value);
        }

SetValue方法是通常的通知属性

 protected virtual Boolean SetValue<T>(ref T field, T value, 
            [CallerMemberName]String propertyName = null)
        {
            if (Equals(field, value))
                return false;
            field = value;
            RaisePropertyChanged(propertyName);
            return true;
        }

属性以通常的方式设置

<Button Content="Cancel" 
        Command="{Binding CancelCommand}" />

ICommand CancelCommand { get; }

private void OnCancel()
{
   UpdateResult = false;
}

免责声明:在我的电脑上工作。

受到Chandrashekhar Joshi答案的启发(但不使用元素名称):

在按钮中定义命令参数:

<Button
  Command="{Binding CloseCommand}"
  CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=Window}}"
  Content="Close" />

定义命令(和实施):

CloseCommand = new DelegateCommand<Window>((w) => w.DialogResult = true);

相关内容

  • 没有找到相关文章

最新更新