如何单向同步两个列表

本文关键字:两个 列表 何单 同步 | 更新日期: 2023-09-27 18:30:58

我有一个列表,列出了一个

列表框中的标签对象。可以为标签分配字体,这些字体可以从组合框中选择。Label 对象通过 FontId 引用 Font 对象。

从列表框中选择标签时,应在组合框中选择相应的字体对象。但是,从组合框中选择字体应将字体"分配"到所选标签,而不在列表框中选择匹配项。这就是为什么我称之为"单向"同步。

我当前的代码在两个方向上同步两个列表,即从组合框中选择一个字体对象会导致在 ListBox 中选择具有相应字体 ID 的标签。

您将在下面找到带有标签和字体模型以及 XAML 的视图模型。

using System.Collections.Generic;
using System.ComponentModel;
namespace WpfApplication1
{
    public class NotifyPropertyChanged : System.ComponentModel.INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public void RaisePropertyChanged(string prop)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(prop));
            }
        }
    }
    public class ViewModel : NotifyPropertyChanged
    {
        public class Label : NotifyPropertyChanged
        {
            public Label(string name, int id)
            {
                this.name = name;
                this.fontId = id;
            }
            string name;
            public string Name 
            {
                get { return name; }
                set
                {
                    if (name == value) return;
                    name = value;
                    RaisePropertyChanged("Name");
                }
            }
            int fontId;
            public int FontId
            {
                get { return fontId; }
                set
                {
                    if (fontId == value) return;
                    fontId = value;
                    RaisePropertyChanged("FontId");
                }
            }
        }
        public class Font : NotifyPropertyChanged
        {
            public Font(string face, int id)
            {
                this.face = face;
                this.id = id;
            }
            int id;
            public int Id
            {
                get { return id; }
                set
                {
                    if (id == value) return;
                    id = value;
                    RaisePropertyChanged("Id");
                }
            }
            string face;
            public string Face
            {
                get { return face; }
                set
                {
                    if (face == value) return;
                    face = value;
                    RaisePropertyChanged("Face");
                }
            }
        }
        List<Label> labels = new List<Label>
        {
            new Label("City", 1),
            new Label("Road", 13),
            new Label("POI", 17),
            new Label("Favorite", 42)
        };
        public IEnumerable<Label> Labels
        {
            get { return labels; }
        }
        List<Font> fonts = new List<Font>
        {
            new Font("Arial 20", 1),
            new Font("Arial 10", 13),
            new Font("Arial 8", 17),
            new Font("Arial 12", 42),
            new Font("Times 12", 47),
            new Font("Times 18", 11)
        };
        public IEnumerable<Font> Fonts
        {
            get { return fonts; }
        }
        Label curLabel;
        public Label CurrentLabel
        {
            get { return curLabel; }
            set
            {
                if (curLabel == value) return;
                curLabel = value;
                RaisePropertyChanged("CurrentLabel");
            }
        }
        Font curFont;
        public Font CurrentFont
        {
            get { return curFont; }
            set
            {
                if (curFont == value) return;
                curFont = value;
                RaisePropertyChanged("CurrentFont");
            }
        }
    }
}

这里是 XAML:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication1"
        Title="MainWindow" Height="216" ResizeMode="NoResize" SizeToContent="Width">
    <WrapPanel Margin="10">
        <ListBox Name="labelListBox" Width="160" Height="130" Margin="10"
                 ItemsSource="{Binding Labels}"
                 DisplayMemberPath="Name"
                 SelectedItem="{Binding CurrentLabel}"
                 SelectedValuePath="FontId"/>
        <ComboBox Name="fontComboBox" Width="160" Height="30" Margin="10" VerticalAlignment="Top"
                  ItemsSource="{Binding Fonts}"
                  DisplayMemberPath="Face"
                  SelectedValuePath="Id"
                  SelectedValue="{Binding ElementName=labelListBox, Path=SelectedValue}"/>
    </WrapPanel>
</Window>

和代码隐藏:使用系统视窗;

namespace WpfApplication1
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = new ViewModel();
        }
    }
}

感谢您的提示!

如何单向同步两个列表

简单的解决方案是将绑定Mode(在 ComboBox 中)设置为OneWay

<ComboBox Name="fontComboBox" Width="160" Height="30" Margin="10" 
          VerticalAlignment="Top"
          ItemsSource="{Binding Fonts}"
          DisplayMemberPath="Face"
          SelectedValuePath="Id"
          SelectedValue="{Binding ElementName=labelListBox, Path=SelectedValue,
                                  Mode=OneWay}"/>

现在,在列表框中选择时,其SelectedValue将更改,从而使组合框的选定值更改。SelectedValuePath将实际的选定值解析为Id成员,并将选择匹配的项。由于我们将绑定模式设置为 OneWay ,因此从组合框中选择项以及更改组合框的SelectedValue不会反映到 ListBox 的选定值。

xaml 中的小更正如下。希望这是你想要的,它有帮助。

<Window x:Class="WpfApplication2.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication2"
    Title="MainWindow" Height="216" ResizeMode="NoResize" SizeToContent="Width">
<WrapPanel Margin="10">
    <ListBox Name="labelListBox" Width="160" Height="130" Margin="10"
             ItemsSource="{Binding Labels}"
             DisplayMemberPath="Name"
             SelectedItem="{Binding CurrentLabel}"
             FontSize="{Binding ElementName=fontComboBox , Path=SelectedValue.Id}"
             FontFamily="{Binding ElementName=fontComboBox, Path=SelectedValue.Face}"/>
    <ComboBox Name="fontComboBox" Width="160" Height="30" Margin="10" VerticalAlignment="Top"
              ItemsSource="{Binding Fonts}"                  
              DisplayMemberPath="Face"
              SelectedValue="{Binding CurrentFont}"/>
   </WrapPanel>