WPF绑定ListBox主/详细信息

时间:2011-09-21 10:29:32

标签: c# wpf binding .net-3.5

我可以使用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。或者也许我没有说出正确的搜索咒语。

有一天,我可能突然明白了解这个有约束力的东西,但此刻它让我感到困惑。任何帮助表示赞赏。

2 个答案:

答案 0 :(得分:14)

正确的方法是使用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));
        }
    }
}

在View的代码中初始化它,如下所示:

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绑定会在其SelectedPerson(即DataContext)中查找属性MainWindowViewModel,并在Name中查找属性SelectedPerson 1}}。

此示例的基本机制如下: ViewModel上的SelectedPerson属性始终与SelectedItem的{​​{1}}同步,ListBox的{​​{1}}属性始终与{{1}同步Text的属性。

答案 1 :(得分:0)

尝试从People

继承您的ObservableCollection<Person>班级