2015-09-09 225 views
0

我有一個UserControl包含一個ListBox,我想跟蹤該列表框的SelectedItems。 的用戶控件有一個DP「SelectedItemsList」是這樣定義的綁定到usercontrol中的依賴屬性

public static DependencyProperty SelectedItemsListProperty = DependencyProperty.Register(
    "SelectedItemsList", 
    typeof (IList), 
    typeof (MyListControl), 
    new FrameworkPropertyMetadata(null, 
    OnSelectedItemsChanged)); 

ListBox中的」項目‘的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的值始終爲空。

我知道這個問題類似於Dependency property callback does not work,但在那裏發佈的答案並不能解決我的問題。

我在這裏錯過了什麼?

感謝,

編輯(2015年9月10日): 謝謝大家的意見。我找到了適合我需求的解決方案:

首先,我創建了一個自定義列表框控件,它提供依賴項屬性中的所選項目列表(非常類似於Select multiple items from a DataGrid in an MVVM WPF project)。

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

我不是用「新的ArrayList」雙組分幸福了,但如果我的視圖模型的屬性setter我要檢查平等,SelectedItemsList不能SelectedItems的參考。以前和新的價值將永遠是一樣的。

然後我我的用戶「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); 
     } 
     } 
} 

重要的是,類型o f這個屬性是IList,否則setter中的值將始終爲空。

並在視圖的XAML

<controls:MyListControl 
    Source="{Binding CurrentImageList, UpdateSourceTrigger=PropertyChanged}" 
    SelectedItems="{Binding SelectedObjects, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
/> 
+0

[Dependency property callback does not work]的可能重複(http://stackoverflow.com/questions/6584463/dependency-property-callback-does-not-工作) –

+0

當我添加「SelectedItemsList = null;」在「OnItemSelectionChanged」中的常規設置之前,propertychangecallabck被觸發(對於這兩個集合),但對我的ViewModel的綁定仍然始終包含「null」。 – tabina

回答

0

我有同樣的問題今天,不幸的是,當你分配給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); 
      } 
     } 
    } 
0

你需要綁定你的ListBox的SelectedItems到DP SelectedItemsList傳播用戶選擇的DP。您已經擁有的綁定會將更改傳遞給viewmodel,但我認爲您需要綁定模式「twoway」而不是UpdateSourceTrigger。

並且不要在DP中使用PropertyChangeCallback:如果SelectedItemsListProperty已更改,則更改SelectedItemsList是沒有意義的。 (通常前者是後者的包裝屬性。)

+0

我只是使用PropertyChangeCallback來設置斷點來查看是否發生了任何更改。 – tabina

+0

該列表框沒有SelectedItems屬性的公共setter。所以我不能直接綁定它。 – tabina