将DialogResult视图绑定到ViewModels属性?

时间:2011-06-20 08:00:01

标签: wpf xaml data-binding binding dialogresult

我对WPF,XAML和数据绑定相对较新。我有一个视图(Window)和一个视图模型。

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

到目前为止一直很好,但现在我遇到了一个问题,我无法找到解决方案。

在我的视图中,我有一个按钮Start,它与命令绑定。

<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;

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

提前感谢您的帮助!

PS:我的问题很明确。如果有任何不清楚的地方,请随时询问。

4 个答案:

答案 0 :(得分:1)

您可以将窗口引用作为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();
}

答案 1 :(得分:0)

CommandParameter =&#34; {Binding ElementName = Window}&#34;假设您的XAML中有一个名为&#34; Window&#34;的元素。例如,您的Window标记需要&#39; Name =&#34; Window&#34;&#39;

答案 2 :(得分:0)

这个问题是我用Google搜索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方法是通常的notify属性

 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;
}

免责声明:可在我的计算机上使用。

答案 3 :(得分:-1)

灵感来自 Chandrashekhar Joshi 的回答 (但不使用元素的名称):

在按钮中定义命令参数:

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

定义命令(和实现):

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