Reputation: 796
I have a customlistbox whose itemssource is bound to an observablecollection in the viewmodel. I have created a SelectedItemsList DependencyProperty in the customListbox so that the user can select items and the viewmodel will updated. This works perfectly.
I would also like the bound list in the viewmodel, when changed, to update the selected items in the 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 is read only. Is there anyway to update the selected items from the viewModel? Is there an alternative to ListBox that would be more suitable?
Upvotes: 1
Views: 479
Reputation: 796
I figured that I would post my solution just in case it helps anyone.
Here is my very simple Item class
class MyItem
{
public string MyString { get; set; }
public MyItem(string m)
{
MyString = m;
}
}
Here is my CustomListBox Code
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
}
The XAML Binding in my window
<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>
And my 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;
}
}
Upvotes: 1