Я хочу использовать SelectionChangeEvent ListBox в MVVM - PullRequest
0 голосов
/ 18 января 2019

Прежде всего, я хорошо разбираюсь в английском. Поэтому извините, если скажу, что вы не можете понять.

У меня есть приложение WPF с 2 списками. И я хочу переделать приложение как MVVM.

Но я не знаю, как кодировать событие SelectionChanged как MVVM.

Я попробовал этот код.

В коде просмотра он содержит комментарий. Это код, который я добавляю, тогда я получаю совет, мой друг. (Но это тоже не работа.)

// View

    xmlns:xcad="http://schemas.xceed.com/wpf/xaml/toolkit"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <ListBox HorizontalAlignment="Left" Height="56" Margin="64,67,0,0" VerticalAlignment="Top" Width="380" SelectedItem="{Binding SelectColorList}" ItemsSource="{Binding ColorList}"/>
    <ListBox HorizontalAlignment="Left" Height="56" Margin="64,182,0,0" VerticalAlignment="Top" Width="380" ItemsSource="{Binding ItemList}"/>

    <!--<xcad:CheckListBox HorizontalAlignment="Left" Height="56" Margin="64,67,0,0" VerticalAlignment="Top" Width="380" SelectedItemsOverride="{Binding SelectColorList}" ItemsSource="{Binding ColorList}"/>
    <xcad:CheckListBox HorizontalAlignment="Left" Height="56" Margin="64,182,0,0" VerticalAlignment="Top" Width="380" ItemsSource="{Binding ItemList}"/>-->

    <Label Content="Color" HorizontalAlignment="Left" Height="24" Margin="65,38,0,0" VerticalAlignment="Top" Width="65"/>
    <Label Content="Item" HorizontalAlignment="Left" Height="24" Margin="64,153,0,0" VerticalAlignment="Top" Width="65"/>
</Grid>

// CodeBehinde

private MainViewModel viewmodel;
public MainWindow()
{
    InitializeComponent();
    viewmodel = new MainViewModel();
    this.DataContext = viewmodel;
}

// ViewModel

public class MainViewModel : INotifyPropertyChanged
{
    private ObservableCollection<string> ColorListVal;
    public ObservableCollection<string> ColorList
    {
        get { return ColorListVal; }
        set
        {
            ColorListVal = value;
            NotifyPropertyChanged("ColorList");

        }
    }

    private ObservableCollection<string> SelectColorListVal = new ObservableCollection<string>();
    public ObservableCollection<string> SelectColorList
    {
        get { return SelectColorListVal; }
        set
        {
            SelectColorListVal = value;
            NotifyPropertyChanged("SelectColorList");

            ItemListVal.Clear();

            for (int i = 0; i < SelectColorList.Count; i++)
            {
                switch (SelectColorList[i])
                {
                    case "red":
                        ItemListVal.Add("apple");
                        ItemListVal.Add("sun");
                        break;

                    case "blue":
                        ItemListVal.Add("sea");
                        ItemListVal.Add("sky");
                        break;

                    case "yellow":
                        ItemListVal.Add("lemmon");
                        ItemListVal.Add("pineapple");
                        break;

                    case "green":
                        ItemListVal.Add("vegetable");
                        ItemListVal.Add("greentea");
                        break;
                }
            }
        }
    }

    private ObservableCollection<string> ItemListVal;
    public ObservableCollection<string> ItemList
    {
        get { return ItemListVal; }
        set
        {
            ItemListVal = value;
            NotifyPropertyChanged("ItemList");
        }
    }



    public MainViewModel()
    {
        ColorListVal = new ObservableCollection<string>() { "red", "blue", "yellow", "green" };
        ItemListVal = new ObservableCollection<string>() { "not selected!" };
    }



    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }
}

Я хочу сделать это ...

@ Если я нажму «красный», в списке элементов будут показаны «яблоко» и «солнце» в виде ListBox. Тогда, если я нажму синий ... это то же самое.

@ Хочу щелкнуть многоцветным! Поэтому, если я нажму на красный и синий, список пунктов будет «яблоко», «солнце», «море» и «небо». (Но мне все равно порядок списка)

@ Список (как по цвету, так и по предмету) не совпадает. Поэтому я хочу установить содержимое как динамическое и добавить элементы как динамическое.

Что мне переделать этот код?

Ответы [ 2 ]

0 голосов
/ 18 января 2019

В Xaml вам необходимо привязать свойство SelectedItem к строке (не к списку / коллекции)

<ListBox SelectedItem="{Binding SelectColor}" ItemsSource="{Binding ColorList}"/>
<ListBox ItemsSource="{Binding ItemList}"/>

ViewModel,

private string _selectedColor;
public string SelectedColor
{
    get => _selectedColor;
    set
    {
        _selectedColor = value;
        ItemList.Clear();

        switch (_selectedColor)
        {
            case "red":
               ItemList.Add("apple");
               ItemList.Add("sun");
               break;
        …

   }
   NotifyPropertyChanged(nameof(SelectedColor));
}

Также я бы предложил использовать ItemList вместо ItemListVal (вспомогательное поле) при добавлении / удалении элементов из коллекции.

0 голосов
/ 18 января 2019

в вашем xaml-файле вы привязываете SelectedItem к SelectColorList, который является коллекцией, чтобы исправить это, вы должны привязать к одному значению (к некоторому строковому свойству в вашем случае), а не к коллекции.
UPDATE:
& emsp; Прежде всего, я хочу упомянуть, что нет способа для множественного связывания, поэтому мы будем использовать событие SelectionChanged.
& emsp; Например, это ваш вид, который содержит два списка, один из которых будет содержать источник цветов, который будет иметь возможность выбора нескольких элементов:

<Window x:Class="WpfApp1.MainWindow">
    <StackPanel Orientation="Horizontal">
        <!-- First list box contains colors -->
        <ListBox
            ItemsSource="{Binding ColorList}"
            SelectionMode="Extended"
            SelectionChanged="ListBox_SelectionChanged"
            />
        <!-- Second list box will contain result values -->
        <ListBox
            ItemsSource="{Binding ItemList}"
            />
    </StackPanel>
</Window>


& emsp; Ваш MainWindow.xaml.cs:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        // Set data context
        DataContext = new ViewModel();
    }

    /// <summary>
    /// Called when selection is changed
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void ListBox_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
    {
        // Get event sender
        var listBox = sender as ListBox;
        // Create temp list for selected items
        var tempList = new List<string>();

        foreach (string item in listBox.SelectedItems)
        {
            tempList.Add(item);
        }

        (DataContext as ViewModel).OnSelectionChanged(tempList);
    }
}


& emsp; И, наконец, модель вашего вида:

public class ViewModel : INotifyPropertyChanged
{
    #region Private Fields
    private ObservableCollection<string> mColorList;
    private ObservableCollection<string> mItemList;
    #endregion

    #region Public Properties
    /// <summary>
    /// This is list box 1 items source with colors
    /// </summary>
    public ObservableCollection<string> ColorList
    {
        get { return mColorList; }
        set
        {
            mColorList = value;
            NotifyPropertyChanged(nameof(ColorList));
        }
    }

    /// <summary>
    /// This is list box 2 items with results
    /// </summary>
    public ObservableCollection<string> ItemList
    {
        get { return mItemList; }
        set
        {
            mItemList = value;
            NotifyPropertyChanged(nameof(ItemList));
        }
    }
    #endregion

    #region Constructor
    public ViewModel()
    {
        // Initialization 
        ColorList = new ObservableCollection<string>() { "red", "blue", "yellow", "green" };
        ItemList = new ObservableCollection<string>() { "not selected!" };
    }
    #endregion

    #region Public Methods
    /// <summary>
    /// Called when selection is changed
    /// </summary>
    /// <param name="selectedItems"></param>
    public void OnSelectionChanged(IEnumerable<string> selectedItems)
    {
        ItemList.Clear();
        foreach (var item in selectedItems)
        {
            switch (item)
            {
                case "red":
                    ItemList.Add("apple");
                    ItemList.Add("sun");
                    break;
                case "blue":
                    ItemList.Add("sea");
                    ItemList.Add("sky");
                    break;
            }
        }
    }
    #endregion

    #region InterfaceImplementation
    public event PropertyChangedEventHandler PropertyChanged;

    public void NotifyPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    #endregion
}


& emsp; Вот как это можно сделать. Надеюсь, что этот ответ поможет вам

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...