[英]Binding to dependency property in usercontrol
我有一個包含一個ListBox的UserControl,我想跟蹤該列表框的SelectedItems。 UserControl有一個DP“ SelectedItemsList”,其定義如下
public static DependencyProperty SelectedItemsListProperty = DependencyProperty.Register(
"SelectedItemsList",
typeof (IList),
typeof (MyListControl),
new FrameworkPropertyMetadata(null,
OnSelectedItemsChanged));
在列表框的項目“ SelectionChanged”事件中,我想將所選項目保存到DP。 每當我更改列表框中的選擇時,都會觸發此操作。
private void OnItemSelectionChanged(object sender, SelectionChangedEventArgs e)
{
SelectedItemsList = this.myListBox.SelectedItems;
}
在包含“ MyListControl”的視圖中,我創建了要使用所選項目的視圖模型的綁定。
<controls:MyListControl
Source="{Binding SomeItemsList, UpdateSourceTrigger=PropertyChanged}"
SelectedItemsList="{Binding SelectedItems, UpdateSourceTrigger=PropertyChanged}"/>
我的問題是,DP SelectedItemsList永遠不會更新。 DP的PropertyChangeCallback“ OnSelectedItemsChanged”僅在我最初加載列表內容時觸發。 SelectedItemsList的值始終為null。
我知道這個問題類似於Dependency屬性回調不起作用 ,但是在那里發布的答案不能解決我的問題。
我在這里想念什么?
謝謝,
編輯(2015-09-10):謝謝大家的評論。 我找到了適合我需求的解決方案:
首先,我創建了一個自定義列表框控件,該控件在依賴項屬性中提供了選定項目的列表(非常類似於從MVVM WPF項目中從DataGrid中選擇多個項目 )。
public class CustomListBox : ListBox
{
public static readonly DependencyProperty SelectedItemsListProperty =
DependencyProperty.Register("SelectedItemsList",
typeof (IList),
typeof (CustomListBox),
new PropertyMetadata(null));
public CustomListBox()
{
SelectionChanged += OnSelectionChanged;
}
public IList SelectedItemsList
{
get { return (IList)GetValue(SelectedItemsListProperty); }
set { SetValue(SelectedItemsListProperty, value); }
}
void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
this.SelectedItemsList= new ArrayList(this.SelectedItems);
}
}
我對“ new ArrayList”部分還不滿意,但是如果在我的視圖模型的屬性設置器中我想檢查是否相等,則SelectedItemsList不能是SelectedItems的引用。 以前的值和新的值將始終相同。
然后,將UserControl“ MyListControl”的項目選擇部分簡化為依賴項屬性本身:
public static DependencyProperty SelectedItemsProperty = DependencyProperty.Register(
"SelectedItems",
typeof (IList),
typeof (MyListControl),
new FrameworkPropertyMetadata(null));
public IList SelectedItems
{
get
{
return (IList)GetValue(SelectedItemsProperty);
}
set
{
SetValue(SelectedItemsProperty, value);
}
}
並修改了MyListControl的xaml:
<controls:CustomListBox
SelectionMode="Extended"
ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type controls:MyListControl}},
Path=Source, UpdateSourceTrigger=PropertyChanged}"
SelectedItemsList="{Binding RelativeSource={RelativeSource AncestorType={x:Type controls:MyListControl}},
Path=SelectedItems, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
>
我的ViewModel中的屬性看起來像
public IList SelectedObjects
{
get { return _selectedObjects; }
set { if (this._selectedObjects != value)
{
this._selectedObjects = value;
OnPropertyChanged(SelectedObjectsProperty);
}
}
}
此屬性的類型為IList非常重要,否則設置器中的值將始終為null。
在視圖的xaml中
<controls:MyListControl
Source="{Binding CurrentImageList, UpdateSourceTrigger=PropertyChanged}"
SelectedItems="{Binding SelectedObjects, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
/>
不幸的是,今天我遇到了同樣的問題,當您為SelectedItemsList分配一個值時,WPF似乎將其取消綁定。 為了解決這個問題,我更新了綁定項目中的值。 我知道這不是世界上最好的解決方案,但對我而言,它是有效的。 在這種情況下,代碼如下所示:
private void OnItemSelectionChanged(object sender, SelectionChangedEventArgs e)
{
this.SetPropertyValue(
this.GetBindingExpression(SelectedItemsListProperty),
this.myListBox.SelectedItems);
}
private void SetPropertyValue(BindingExpression bindingExpression, object value)
{
string path = bindingExpression.ParentBinding.Path.Path;
var properties = new Queue<string>(
path.Split(
new[]
{
'.'
}).ToList());
this.SetPropertyValue(bindingExpression.DataItem, bindingExpression.DataItem.GetType(), properties, value);
}
private void SetPropertyValue(object destination, Type type, Queue<string> properties, object value)
{
PropertyInfo property = type.GetProperty(properties.Dequeue());
if (property != null && destination != null)
{
if (properties.Count > 0)
{
this.SetPropertyValue(property.GetValue(destination), property.PropertyType, properties, value);
}
else
{
property.SetValue(destination, value);
}
}
}
您需要將列表框的SelectedItems綁定到DP SelectedItemsList,以將用戶選擇傳播到DP。 然后,您已經擁有的綁定將把更改傳遞給viewmodel,但是我認為您將需要綁定模式“雙向”而不是UpdateSourceTrigger。
並且不要在DP中使用PropertyChangeCallback:如果SelectedItemsListProperty發生了更改,則更改SelectedItemsList是沒有意義的。 (通常,前者是后者的包裝器屬性。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.