listbox选择项绑定从源更新
问题描述:
我有一个自定义列表框,其itemssource绑定到viewmodel中的observablecollection。我在customListbox中创建了SelectedItemsList DependencyProperty,以便用户可以选择项目并更新视图模型。这工作完美。listbox选择项绑定从源更新
我还希望viewmodel中的绑定列表在更改时更新customListbox中的选定项。
static FrameworkPropertyMetadata fpm = new FrameworkPropertyMetadata(
new ObservableCollection<MyItem>(),
(FrameworkPropertyMetadataOptions.AffectsRender |
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault),
new PropertyChangedCallback(OnSelectedItemsChanged)
);
private static void OnSelectedItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
//the code
}
public static readonly DependencyProperty SelectedItemsListProperty =
DependencyProperty.Register("SelectedItemsList",
typeof(ObservableCollection<MyItem>),
typeof(CustomListBox), fpm);
SelectedItems是只读的。无论如何都要更新viewModel中的选定项目吗?有没有替代ListBox,会更合适?
答
我想我会发布我的解决方案,以防万一它帮助任何人。
这是我非常简单的项目类
class MyItem
{
public string MyString { get; set; }
public MyItem(string m)
{
MyString = m;
}
}
这是我CustomListBox代码
class CustomListBox : ListBox
{
public CustomListBox()
{
this.SelectionChanged += CustomListBox_SelectionChanged;
}
void CustomListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ObservableCollection<MyItem> tempList = new ObservableCollection<MyItem>();
foreach (MyItem i in this.SelectedItems)
{
tempList.Add(i);
}
this.SelectedItemsList = tempList;
}
#region SelectedItemsList
public ObservableCollection<MyItem> SelectedItemsList
{
get { return (ObservableCollection<MyItem>)GetValue(SelectedItemsListProperty); }
set { SetValue(SelectedItemsListProperty, value); }
}
public static readonly DependencyProperty SelectedItemsListProperty =
DependencyProperty.Register("SelectedItemsList", typeof(ObservableCollection<MyItem>), typeof(CustomListBox),
new PropertyMetadata(new ObservableCollection<MyItem>(), new PropertyChangedCallback(OnSelectionChanged)));
public static void OnSelectionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
CustomListBox clb = d as CustomListBox;
var selectedItems = e.NewValue as ObservableCollection<MyItem>;
if (selectedItems != null)
{
clb.SetSelectedItems(selectedItems);
}
}
#endregion
}
的XAML在我的窗口
<local:CustomListBox Height="500" Width="200" x:Name="listview" Margin="0,40,0,0" ItemsSource="{Binding MyItemsList}"
Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Top" TabIndex="50"
SelectionMode="Multiple" SelectedItemsList="{Binding SelectedMyItems, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" >
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=MyString}" />
</DataTemplate>
</ListBox.ItemTemplate>
</local:CustomListBox>
约束力和我的ViewModel
class MyViewModel : ViewModelBase
{
public MyViewModel()
{
this.SelectChangeMyItemsCommand = new BaseCommand(new Action(SelectChangeMyItems));
}
private ObservableCollection<MyItem> selectedMyItems = null;
public ObservableCollection<MyItem> SelectedMyItems
{
get
{
if (selectedMyItems == null)
{
selectedMyItems = new ObservableCollection<MyItem>();
}
return selectedMyItems;
}
set
{
selectedMyItems = value;
OnPropertyChanged("SelectedMyItems");
}
}
private ObservableCollection<MyItem> myItemsList = null;
public ObservableCollection<MyItem> MyItemsList
{
get
{
if (myItemsList == null)
{
MyItemsRefresh();
}
return myItemsList;
}
set
{
myItemsList = value;
OnPropertyChanged("MyItemsList");
}
}
public void MyItemsRefresh()
{
ObservableCollection<MyItem> tempMyList = new ObservableCollection<MyItem>();
tempMyList.Add(new MyItem("Angry Apple"));
tempMyList.Add(new MyItem("Big Bird"));
tempMyList.Add(new MyItem("Candy Cane"));
tempMyList.Add(new MyItem("Daring Dart"));
MyItemsList = tempMyList;
}
private static bool iseven = true;
public ICommand SelectChangeMyItemsCommand { get; private set; }
public void SelectChangeMyItems()
{
ObservableCollection<MyItem> items = new ObservableCollection<MyItem>();
for(int i = 0; i < myItemsList.Count; i++)
{
if (iseven && IsEven(i))
{
items.Add(MyItemsList[i]);
}
else if (!iseven && !IsEven(i))
{
items.Add(MyItemsList[i]);
}
}
this.SelectedMyItems = items;
iseven = !iseven;
}
public static bool IsEven(int value)
{
return value % 2 == 0;
}
}
在SelectedItemsList属性的PropertyChangedCallback中,检查分配的集合是否实现INotifyCollectionChanged(例如, ObservableCollection),并附加一个CollectionChanged处理程序。在该处理程序中,将项目添加到SelectedItems集合或从SelectedItems集合中删除项目。搜索*以“绑定SelectedItems”。这个问题已经有其他问题和答案。 – Clemens
propertyChangedCallback似乎只在Windows的初始化中被调用。我会发布一些代码来确认我的dependency.register调用是否合适。 – kurgaan
拍摄。我想到了。我被绑定到错误的可观察集合。 – kurgaan