如何单向同步两个列表
本文关键字:两个 列表 何单 同步 | 更新日期: 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>