列表框选定的项目从源绑定更新

时间:2017-02-24 13:50:11

标签: c# wpf mvvm data-binding listbox

我有一个customlistbox,其itemssource绑定到viewmodel中的observablecollection。我在customListbox中创建了一个SelectedItemsList DependencyProperty,以便用户可以选择项目并更新viewmodel。这非常有效。

我还希望viewmodel中的绑定列表在更改时更新customListbox中的选定项。

{{1}}

SelectedItems是只读的。无论如何都要从viewModel更新所选项目?是否有更适合ListBox的替代方案?

1 个答案:

答案 0 :(得分:0)

我想我会发布我的解决方案以防万一它可以帮助任何人。

这是我非常简单的Item类

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