将视图 DialogResult 绑定到 ViewModels 属性?

发布于 2024-11-16 03:19:27 字数 797 浏览 5 评论 0原文

我对 WPF、XAML 和数据绑定比较陌生。我有一个视图(窗口)和一个视图模型。

我尝试实现 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;

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

I am relatively new to WPF, XAML and Data-bindings. I have a view (Window) and a view-model.

I have tried to implement the MVVM pattern which means neither the view nor the view-model hold a reference to each other. All data exchange happens via data-bindings.

So far so good but now I have run into a problem I can't find a solution for.

On my view I have a button Start which is bound to a command.

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

NextCommand is of type ActionCommand : ICommand

In my case NextCommand simply calls a private method within the view-model.

The problem I can not find a solution so far is the following:

How to close the window at the end of the view-models NextCommandAction method?

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

Since I do not have a reference to the view I can not just set DialogResult = true;

The only working solution I have found so far is to add a hidden radio-button to the view and bind it's value to a property CloseView and create a method CloseView within the xaml.cs file which is bound to the Checked event of the hidden radio-button. Within that method I set DialogResult = true;

Although this works I feel like there has to be a better solution than adding hidden elements to your view!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

浮生未歇 2024-11-23 03:19:27

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

You can pass the window reference as CommandParameter to the Close command and do whatever required on the window.

<Button Content="Close" Command="{Binding Path=CloseCommand}" 
  CommandParameter="{Binding ElementName=Window}"/>

private void CloseCommand(object sender)
{
    Window wnd = sender as Window;
    wnd.Close();
}
醉城メ夜风 2024-11-23 03:19:27

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

CommandParameter="{Binding ElementName=Window}" assumes that you have an element in your XAML named "Window". e.g, your Window tag would need Name="Window"

依 靠 2024-11-23 03:19:27

这个问题是当我用谷歌搜索以检查 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;
}

免责声明:适用于我的计算机。

This question was one of the first things that came up when I googled to check if DialogResult is a dependency property (it isn't :-) )

Add a dependency property to your Window:

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

I named my property InteractionResult though a good name would have also worked.

In the xaml right after the
you can bind it with a style


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

UpdateResult is the property in my viewmodel.

  private Boolean? _updateResult;

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

The SetValue method is the usual notify property

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

and the property gets set in the usual way

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

ICommand CancelCommand { get; }


private void OnCancel()
{
   UpdateResult = false;
}

Disclaimer: works on my computer.

不羁少年 2024-11-23 03:19:27

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

在按钮中定义 CommandParameter:

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

定义命令(和实现):

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

Inspired by Chandrashekhar Joshi's answer
(but not using the elements's name):

Define CommandParameter in Button:

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

Define Command (and Implementation):

CloseCommand = new DelegateCommand<Window>((w) => w.DialogResult = true);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文