2017-08-26 37 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

謝謝,它的工作原理非常好,這是一個簡單的解決方案。 –