WPF绑定列表框主/详细信息

本文关键字:详细信息 绑定 列表 WPF | 更新日期: 2023-09-27 18:09:08

我可以使用XmlDataSource,但不能使用我自己的类。我要做的就是将列表框绑定到集合实例,然后将文本框链接到列表框,这样我就可以编辑该人的姓名(双向)。我故意使这篇文章尽可能简单,希望有人能填补空白。

XAML:

<Window x:Class="WpfListTest.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfListTest"
    Title="Window1" Height="300" Width="600">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="160"/>
            <ColumnDefinition Width="3"/>
            <ColumnDefinition Width="1*"/>
        </Grid.ColumnDefinitions>
        <DockPanel Grid.Column="0">
            <ListBox />
        </DockPanel>
        <DockPanel Grid.Column="2">
            <StackPanel>
                <Label>Name</Label>
                <TextBox />
            </StackPanel>
        </DockPanel>
    </Grid>
</Window>

c#代码:

namespace WpfListTest
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        public People MyPeeps = new People();
        public Window1()
        {
            InitializeComponent();
            MyPeeps.Add(new Person("Fred"));
            MyPeeps.Add(new Person("Jack"));
            MyPeeps.Add(new Person("Jill"));
        }
    }
    public class Person
    {
        public string Name { get; set; }
        public Person(string newName)
        {
            Name = newName;
        }
    }
    public class People : List<Person>
    {
    }
}

web上的所有示例似乎都有一个有效的静态类返回代码定义的数据(如返回new Person("blah blah")),而不是我自己的集合实例-在这种情况下是MyPeeps。也可能是我没有念对搜索咒语。

有一天我可能会突然突破理解这种绑定的东西,但现在它让我困惑。

WPF绑定列表框主/详细信息

正确的方法是使用MVVM模式并创建一个ViewModel,如下所示:

public class MainWindowViewModel : INotifyPropertyChanged
{
    private People _myPeeps;
    private Person _selectedPerson;
    public event PropertyChangedEventHandler PropertyChanged;
    public People MyPeeps
    {
        get { return _myPeeps; }
        set
        {
            if (_myPeeps == value)
            {
                return;
            }
            _myPeeps = value;
            RaisePropertyChanged("MyPeeps");
        }
    }
    public Person SelectedPerson
    {
        get { return _selectedPerson; }
        set
        {
            if (_selectedPerson == value)
            {
                return;
            }
            _selectedPerson = value;
            RaisePropertyChanged("SelectedPerson");
        }
    }
    private void RaisePropertyChanged(string propertyName)
    {
        var handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

在视图后面的代码中初始化它,如下所示:

public partial class MainWindow : Window
{
    private readonly MainWindowViewModel _viewModel;
    public MainWindow()
    {
        _viewModel = new MainWindowViewModel();
        _viewModel.MyPeeps = new People();
        _viewModel.MyPeeps.Add(new Person("Fred"));
        _viewModel.MyPeeps.Add(new Person("Jack"));
        _viewModel.MyPeeps.Add(new Person("Jill"));
        DataContext = _viewModel;
        InitializeComponent();
    }
}

并像这样绑定数据:

<Window x:Class="WpfApplication3.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow"
        Height="350"
        Width="525">
  <Grid>
    <Grid.ColumnDefinitions>
      <ColumnDefinition Width="160" />
      <ColumnDefinition Width="3" />
      <ColumnDefinition Width="1*" />
    </Grid.ColumnDefinitions>
    <DockPanel Grid.Column="0">
      <ListBox SelectedItem="{Binding SelectedPerson}"
               DisplayMemberPath="Name"
               ItemsSource="{Binding MyPeeps}" />
    </DockPanel>
    <DockPanel Grid.Column="2">
      <StackPanel>
        <Label>Name</Label>
        <TextBox Text="{Binding SelectedPerson.Name}" />
      </StackPanel>
    </DockPanel>
  </Grid>
</Window>

绑定是这样工作的:

窗口本身的DataContext被设置为ViewModel实例。因为ListBox和TextBox没有指定任何DataContext,它们从Window继承它。如果没有指定其他内容,对象上的绑定总是相对于DataContext工作。这意味着TextBox绑定在其DataContext(即MainWindowViewModel)中查找属性SelectedPerson,并在该SelectedPerson中查找属性Name

这个示例的基本机制如下:ViewModel上的SelectedPerson属性总是与ListBoxSelectedItem属性同步,TextBoxText属性总是与SelectedPersonName属性同步。

尝试从ObservableCollection<Person>继承People