2010-03-30 15 views
7

W WinForms możemy określić DialogResult dla przycisków. W WPF możemy zadeklarować w XAML tylko Cancel:Deklaracja WPF DialogResult?

<Button Content="Cancel" IsCancel="True" /> 

Dla innych musimy złapać ButtonClick i napisać kod tak:

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

Używam MVVM, więc mam tylko kod XAML dla Windows. Ale w przypadku okien modalnych muszę napisać taki kod i nie podoba mi się to. Czy istnieje bardziej elegancki sposób na takie rzeczy w WPF?

+0

Duplikat: http://stackoverflow.com/questions/ 501886/wpf-mvvm-newbie-how-should-the-viewmodel-close-the-form –

+0

Kiedyś czułam w ten sposób używanie kodu z MVVM, ale szczerze mówiąc, myślę, że ustawienie pojedynczej flagi w kodzie za * jest * najbardziej eleganckie rozwiązanie. Po co walczyć. Nie ma sensu pisać złożonego przywiązania do zachowania z niewielkim zyskiem. – craftworkgames

Odpowiedz

2

Możesz to zrobić, używając attached behavior, aby utrzymać swoją MVVM w czystości. Kod C# dla załączonym zachowanie może wyglądać tak:

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

Można użyć właściwości w XAML z poniższym kodzie:

<Button local:IsAccept="True">OK</Button> 
+0

Nie wiem, dlaczego nie zaznaczył twojej odpowiedzi, ale głosuję w górę za użyteczny przycisk akceptacji stylu MVVM. Zachowania interakcji mogą to zrobić, ale dla mnie jest to zbyt szczegółowe, jeśli chodzi o coś tak prostego. – Alan