Я хочу создать прикрепленное свойство, чтобы иметь доступ к SelectedItems спискаBox в моей модели представления.
Самый простой пример с прикрепленным свойством (для textBox, а не для lIstBox, но для первого изучения думаю достаточно):
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 для метода, обрабатывающего текст.
Сомневаюсь, что нет отписки на событие, когда оно не нужно.
В моем случае я буду использовать прикрепленное свойство в диалоговом окне, поэтому я создам свое представление, свою модель представления, и я буду использовать прикрепленное свойство, которое подпишется на событие, однако, когда я закрою диалоговое окно, событие не отписываться.
На самом деле я бы увидел еще один пример с прикрепленным поведением, но для меня это немного сложнее, и я действительно не знаю разницы между прикрепленными свойствами и присоединенным поведением, поэтому в этом случае я хотел бы научиться использовать прикрепленное имущество.
Другой пример:
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 равно true, и тогда он никогда не подпишет новый диалог на событие.
Во всяком случае, в этом случае у меня есть такое же сомнение, что я не вижу, когда событие будет отписано, когда я закрываю диалог.
Спасибо.