WPF 在 ViewModel 中绑定 Listbox SelectedItem

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26480975/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 12:38:11  来源:igfitidea点击:

WPF binding Listbox SelectedItem in ViewModel

c#wpfxamlmvvmlistbox

提问by

I'm working on a WPF application. The main page is made up of a grid with 2 column and one row. on the first column i have a listbox and on the 2nd column i have a stackpanel named thePanel which i want to change on selected item of a listbox.i first implemented this in the View(mainwindow.xaml.cs) with the selectionChanged event of the Listbox and it worked. I tried to apply the MVVM so i had to do it in the viewModel. the Data Context of the mainwindow is set in its constructor and is of Type UserViewModel. The userViewModel has a property of Type ListBoxItem named SelectedItem which is bound in XAML to the SelectedItem of my listbox. Whenever that is changed, I go up in the UserViewModel with "Parent" until MainWindow and then remove all the children of thePanel and add what I want. The EntriesUC is an UserControl that takes the dataContext in the constructor parameter. There is no problem with it since it worked when i implemented SelectionChanged in the View. The problem is whenever I click any item of the listbox, nothing happens.

我正在开发 WPF 应用程序。主页由一个 2 列和 1 行的网格组成。在第一列我有一个列表框,在第二列我有一个名为 thePanel 的堆栈面板,我想在列表框的选定项目上更改它。我首先在 View(mainwindow.xaml.cs) 中使用 selectionChanged 事件实现了这个列表框,它起作用了。我尝试应用 MVVM,所以我必须在 viewModel 中进行。主窗口的数据上下文在其构造函数中设置,并且类型为 UserViewModel。userViewModel 有一个名为 SelectedItem 的 ListBoxItem 类型属性,它在 XAML 中绑定到我的列表框的 SelectedItem。每当更改时,我都会使用“父级”进入 UserViewModel 直到 MainWindow,然后删除 thePanel 的所有子项并添加我想要的内容。EntriesUC 是一个 UserControl,它在构造函数参数中采用 dataContext。它没有问题,因为当我在视图中实现 SelectionChanged 时它可以工作。问题是每当我单击列表框的任何项目时,什么也没有发生。

Main window:

主窗口:

<Window x:Class="SyntheticLTM.View.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:viewNamespace="clr-namespace:SyntheticLTM.View"
        Title="MainWindow" WindowState="Maximized" Height="350" Width="525">

    <StackPanel>
        //MENU IMPLEMENTATIOn

        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="1*"/>
                <ColumnDefinition Width="4*"/>
            </Grid.ColumnDefinitions>

            <StackPanel Grid.Column="0">
                <Button Content="{Binding Name}" Width="84" />
                <ListBox Name="mainListBox" SelectionMode="Single" SelectedItem="{Binding SelectedItem, Mode=TwoWay}">
                    <ListBoxItem>Data entries</ListBoxItem>
                    <ListBoxItem>Categories</ListBoxItem>
                    <ListBoxItem>Favorites</ListBoxItem>
                    <ListBoxItem>Search</ListBoxItem>
                </ListBox>
            </StackPanel>

            <StackPanel Name="thePanel" Grid.Column="1"  />

        </Grid>
    </StackPanel>

</Window>

UserViewModel:

用户视图模型:

private ListBoxItem selectedItem;
 public ListBoxItem SelectedItem
            {
                get
                {
                    return selectedItem;
                }
                set
                {
                    selectedItem = value;
                    RaisePropertyChanged("SelectedItem");

                    var thePanel = new StackPanel();
                    thePanel=((((((selectedItem as ListBoxItem).Parent as ListBox).Parent as StackPanel).Parent as Grid).Parent as StackPanel).Parent as MainWindow).thePanel;
                    string message;
                    message = selectedItem.ToString();

                    if (message == "Data entries")
                    {
                        var allEntries = new CategoryViewModel();

                        foreach (var category in (thePanel.DataContext as UserViewModel).Categories)
                            allEntries.Entries = new ObservableCollection<EntryViewModel>(category.Entries);

                        thePanel.Children.Clear();
                        thePanel.Children.Add(new EntriesUC(allEntries));
                    }
// implementation for all the other list items...
                 }
               }

采纳答案by Fratyx

Normally you wouldn't add ListBoxItems to the ListBox but you would directly add the strings and would work with a string as SelectedItem. The ListBox would wrap each string with a ListBoxItem automatically. But if you want to do it this way, you have to extract the selected string by

通常您不会将 ListBoxItems 添加到 ListBox,但您会直接添加字符串并将字符串用作 SelectedItem。ListBox 会自动用 ListBoxItem 包装每个字符串。但是如果你想这样做,你必须通过以下方式提取选定的字符串

message = selectedItem.Content.ToString();

message = selectedItem.Content.ToString();