kurgaan
kurgaan

Reputation: 796

listbox selected items binding update from source

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

Answers (1)

kurgaan
kurgaan

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

Related Questions