WPF如何以声明方式设置DialogResult?

7
在WinForms中,我们可以为按钮指定DialogResult。在WPF中,我们只能在XAML中声明Cancel按钮:
<Button Content="Cancel" IsCancel="True" />

对于其他人,我们需要捕获ButtonClick并编写以下代码:

private void Button_Click(object sender, RoutedEventArgs e)
{
    this.DialogResult = true;
}

我正在使用MVVM,因此我只有Windows的XAML代码。但是对于模态窗口,我需要编写这样的代码,而我不喜欢这样。在WPF中是否有更优雅的方法来实现这些操作?


重复:https://dev59.com/nXRB5IYBdhLWcg3wz6ad - Joe White
我曾经对使用MVVM的代码后台感到这种方式,但老实说,我认为在代码后台设置单个标志最优雅的解决方案。为什么要与之斗争呢?没有必要为了很少的收益而编写复杂的附加行为。 - craftworkgames
2个回答

2
你可以使用附加行为来保持你的MVVM整洁。你的附加行为的C#代码可能如下所示:
public static class DialogBehaviors
{
    private static void OnClick(object sender, RoutedEventArgs e)
    {
        var button = (Button)sender;

        var parent = VisualTreeHelper.GetParent(button);
        while (parent != null && !(parent is Window))
        {
            parent = VisualTreeHelper.GetParent(parent);
        }

        if (parent != null)
        {
            ((Window)parent).DialogResult = true;
        }
    }

    private static void IsAcceptChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        var button = (Button)obj;
        var enabled = (bool)e.NewValue;

        if (button != null)
        {
            if (enabled)
            {
                button.Click += OnClick;
            }
            else
            {
                button.Click -= OnClick;
            }
        }
    }

    public static readonly DependencyProperty IsAcceptProperty =
        DependencyProperty.RegisterAttached(
            name: "IsAccept",
            propertyType: typeof(bool),
            ownerType: typeof(Button),
            defaultMetadata: new UIPropertyMetadata(
                defaultValue: false,
                propertyChangedCallback: IsAcceptChanged));

    public static bool GetIsAccept(DependencyObject obj)
    {
        return (bool)obj.GetValue(IsAcceptProperty);
    }

    public static void SetIsAccept(DependencyObject obj, bool value)
    {
        obj.SetValue(IsAcceptProperty, value);
    }
}

您可以使用以下代码在XAML中使用该属性:
<Button local:IsAccept="True">OK</Button>

我不知道为什么他没有标记你的答案,但我会点赞你有用的MVVM风格接受按钮。交互行为可以做到这一点,但对于如此简单的事情来说,这太冗长了。 - Alan

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接