如何将itemscontrol中组合框的选择绑定到与WPF中用作itemssource的列表不同的列表

sg3maiej  于 2023-01-21  发布在  其他
关注(0)|答案(1)|浏览(154)

这涉及WPF和MVVM,
我有一个未排序的项目列表(例如,“item 3,item 2,item 5,item 1,item 4”)。对于每个项目,我希望显示与项目数量相等的组合框(对于 n 个项目,需要有 n 个组合框)。然后用户为每个组合框选择一个项目,实际上是对列表进行排序(产生“item 1,item 2,item 3,item 4,item 5.”的列表)。排序后的值然后存储在另一个项目列表中。排序必须由用户完成。
我有一个包含两个列表的ViewModel,一个包含unsortedItems,sortedList最初是大小相同的副本。
我为每个项目手动创建了一个组合框,所有项目都有相同的Itemssource绑定到未排序的项目列表,然后我用一个表示组合框的索引绑定每个组合框SelectedItem,即第一个组合框SelectedItem="{binding SortedList[0]}"。
这种方法的问题是我不知道会有多少个项目,我以为Itemscontrol可以完成这个任务,但是我似乎不知道如何在itemscontrol中嵌入一个combobox,这样我就可以正确地使用DisplayMemberPath和SelectedItem,并且不共享所选的值。

项目

public class Item
    {
        public Item(int id, string name)
        {
            Id = id;
            Name = name;
        }

        public int Id { get; set; }
        public string Name { get; set; }
        
    }

项目选择部分

public class ItemSelectionPart
    {
        public ItemSelectionPart(List<Item> allItems)
        {
            this.allItems = allItems;
        }

        public List<Item> allItems { get; set; }

        public Item Selection { get; set; }

    }

视图模型

public class ComboViewModel
    {
        public string test2 { get; set; }
        public List<Item> items { get; set; }

        public ObservableCollection<ItemSelectionPart> ItemsSelection { get; set; }

        public ComboViewModel()
        {
            test2 = "test";
            items = new List<Item>
                    {
                        new Item(100, "Entry #1"),
                        new Item(101, "Entry #2"),
                        new Item(102, "Entry #3"),
                        new Item(103, "Entry #4")

                    };

            ItemsSelection = new ObservableCollection<ItemSelectionPart> (Enumerable.Repeat(new ItemSelectionPart(items), items.Count));
        }

    }

主窗口XAML

<Window x:Class="TestingComboBox.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:TestingComboBox"
        d:DataContext="{d:DesignInstance Type=local:ComboViewModel}"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <StackPanel>
        <ItemsControl
            x:Name="level1"
            ItemsSource="{Binding ItemsSelection}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <ComboBox
                            x:Name="Combo"
                            ItemsSource="{Binding Path=allItems}"
                            DisplayMemberPath="{Binding Path=allItems.Id}"
                            SelectedValue="{Binding Path=Selection}">                           

                        </ComboBox>
                    </StackPanel>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </StackPanel>
</Window>
  • 我知道displaymemberpath不起作用-但我还是按我的意愿留了下来 *

主窗口. cs

public partial class MainWindow : Window
    {
        private ComboViewModel D;
        public MainWindow()
        {
            InitializeComponent();
            D = new ComboViewModel();
            this.DataContext = D;
        }
    }
vq8itlhq

vq8itlhq1#

共享的问题是,使用Enumerable.Repeat(new ItemSelectionPart(items), items.Count)时,您创建了一个具有相同示例new ItemSelectionPart(items)的枚举。稍后,您在每个组合框中使用相同的示例,修改它会影响所有组合框。
DisplayMemberPath只获取字符串,而不是绑定。
请参阅修复程序:

<ItemsControl ItemsSource="{Binding ItemsSelection}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <ComboBox
                x:Name="Combo"
                ItemsSource="{Binding Path=allItems}"
                    DisplayMemberPath="Name"
                    SelectedValue="{Binding Selection}">
                </ComboBox>
            </StackPanel>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

public ComboViewModel()
{
    test2 = "test";
    items = new List<Item>
            {
                new Item(100, "Entry #1"),
                new Item(101, "Entry #2"),
                new Item(102, "Entry #3"),
                new Item(103, "Entry #4")
            };
    var selPartList = new List<ItemSelectionPart>(items.Count);
    for (int i = 0; i < items.Count; i++)
    {
        selPartList.Add(new ItemSelectionPart(items));
    }
    ItemsSelection = new ObservableCollection<ItemSelectionPart>(selPartList);
    //ItemsSelection = new ObservableCollection<ItemSelectionPart>(Enumerable.Repeat(new ItemSelectionPart(items), items.Count));
}

相关问题