2017-08-26 42 views
0

我想创建一个附加属性,以访问我的视图模型中的列表框的SelectedItems。何时何地取消订阅对话中的附加属性?

有关附加属性的最简单的例子是这样的(对于一个文本框,而不是列表框,但对于第一次学习,我认为这是不够的):

public static bool GetAllowOnlyString(DependencyObject obj) 
{ 
    return (bool)obj.GetValue(AllowOnlyStringProperty); 
} 
public static void SetAllowOnlyString(DependencyObject obj, bool value) 
{ 
    obj.SetValue(AllowOnlyStringProperty, value); 
} 
// Using a DependencyProperty as the backing store for AllowOnlyString. This enables animation, styling, binding, etc... 
public static readonly DependencyProperty AllowOnlyStringProperty = 
DependencyProperty.RegisterAttached("AllowOnlyString", typeof(bool),typeof(TextblockExtension), new PropertyMetadata(false, AllowOnlyString)); 
private static void AllowOnlyString(DependencyObject d, DependencyPropertyChangedEventArgs e) 
{ 
    if (d is TextBox) 
    { 
     TextBox txtObj = (TextBox)d; 
     txtObj.TextChanged += (s, arg) => 
     { 
     TextBox txt = s as TextBox; 
     if (!Regex.IsMatch(txt.Text, "^[a-zA-Z]*$")) 
     { 
      txtObj.BorderBrush = Brushes.Red; 
      MessageBox.Show("Only letter allowed!"); 
     } 
     }; 
    } 
} 

我可以看到,如果对象是TextBox,那么它将事件TextChanged标记为处理文本的方法。

我的疑问是,当不需要的时候没有对事件取消提交。

在我的情况下,我将在对话框中使用附加的属性,所以我将创建我的视图,我的viewModel,我将使用它将订阅该事件的附加属性,当我关闭对话框时,该活动不退订。

真的,我会看到另一个附加行为的例子,但对我来说它有点复杂,我真的不知道附加属性和附加行为之间的区别,所以在这种情况下,我想学习使用附加属性。

另一个例子是这样的:

public class ListBoxSelectedItemsAttachedProperty 
    { 
     #region SelectedItems 
     private static ListBox list; 
     private static bool _isRegisteredSelectionChanged = false; 

     /// 
     /// SelectedItems Attached Dependency Property 
     /// 
     public static readonly DependencyProperty SelectedItemsProperty = 
     DependencyProperty.RegisterAttached("SelectedItems", typeof(IList), 
     typeof(ListBoxSelectedItemsAttachedProperty), 
     new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault 
      ,new PropertyChangedCallback(OnSelectedItemsChanged) 
      )); 

     public static IList GetSelectedItems(DependencyObject d) 
     { 
      return (IList)d.GetValue(SelectedItemsProperty); 
     } 

     public static void SetSelectedItems(DependencyObject d, IList value) 
     { 
      d.SetValue(SelectedItemsProperty, value); 
     } 

     private static void OnSelectedItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
     { 
      if (!_isRegisteredSelectionChanged) 
      { 
       ListBox listBox = (ListBox)d; 
       list = listBox; 
       listBox.SelectionChanged += listBox_SelectionChanged; 
       _isRegisteredSelectionChanged = true; 
      } 
     } 

     private static void listBox_SelectionChanged(object sender, SelectionChangedEventArgs e) 
     { 
      //Get list box's selected items. 
      IEnumerable listBoxSelectedItems = list.SelectedItems; 
      //Get list from model 
      IList ModelSelectedItems = GetSelectedItems(list); 

      //Update the model 
      ModelSelectedItems.Clear(); 

      if (list.SelectedItems != null) 
      { 
       foreach (var item in list.SelectedItems) 
        ModelSelectedItems.Add(item); 
      } 
      SetSelectedItems(list, ModelSelectedItems); 
     } 
     #endregion 
    } 

当我打开对话框第一次它的工作原理,但如果我关闭和对话,并再次开放,这是行不通的,因为静态属性isRegisteredSelectionChanged是真实的,那么它将永远不会订阅新事件的对话框。

无论如何,在这种情况下,我有同样的疑问,我没有看到当我关闭对话框时事件将被取消订阅。

谢谢。

回答

1

如果你的对话框结束后删除,你可以尝试一点点黑客:

private static void AllowOnlyString(DependencyObject d, DependencyPropertyChangedEventArgs e) 
{ 

    if (d is TextBox) 
    { 
     TextBox txtObj = (TextBox)d; 
     txtObj.TextChanged += Validation; 
     txtObj.Unloaded += Unload; 

    } 
} 

private static void Unload(object sender, RoutedEventArgs e) 
{ 
    var x = (TextBox)sender; 
    x.Unloaded -= Unload; 
    x.TextChanged -= Validation; 
} 

private static void Validation(object sender, TextChangedEventArgs e) 
{  
    TextBox txtObj = sender as TextBox; 
    if (!Regex.IsMatch(txtObj.Text, "^[a-zA-Z]*$")) 
    { 
     txtObj.BorderBrush = Brushes.Red; 
     MessageBox.Show("Only letter allowed!"); 
    } 

} 
+0

谢谢,它的工作原理非常好,这是一个简单的解决方案。 –