访问列表框中的数据

时间:2011-11-01 15:59:29

标签: c# wpf data-binding combobox listbox

嘿我需要访问我在WPF中制作的列表框中的项目。我现在拥有的是用户可以向ListBox.ItemsSource绑定的ObservableCollection添加一个新的类对象。这个类中包含数据,其中数据用于组合框,文本框和其他类似的简单事物。

我所做的实际上是基于来自windowsclient.net的其中一个tut视频

    //Here's What I have so far
    <ListBox x:Name="MyList" Width = "300" Height = 300">
         <ListBox.ItemTemplate>
              <DataTemplate>
                   <StackPanel Orientation="Vertical">
                        <TextBlock x:Name="ItemName" 
                         Text={Binding Path=PersonName}/>
                        <ComboBox x:Name="NumberOfRes" 
                         SelectedIndex="0"
                         SelectionChanged="NumberOfRes_SelectionChanged"
                         ItemsSource={Binding Path=ListOfNums}/>
                   </StackPanel>
              </DataTemplate>
         </ListBox.ItemTemplate>
    </ListBox>

    //ListOfNums
    private ObservableCollection<int> _listofNums = 
                     new ObservableCollection<int>()
    { 1,2,3,4,5,6,7,8 };
    public ObservableCollection<int> ListOfNums
    {
         get{return _listOfNums;}
    }

    //class Resident
    public class Resident
    {
        public string personName {get;set;}
    }

所以我有那个工作。我有一个按钮,添加一个新的类对象,每个对象通过数据绑定正确设置数据。所以当添加一个新对象时我可以看到我的默认personName,并且我有一个用ListOfNums中的整数填充的comboBox。

我的问题是,我不知道如何访问这些'子对象'(原谅我,我是WPF的新手,并且不知道正确的术语)正在选择。我想知道在引发selectionChange事件时我的comboBox的SelectedItem是什么,或者当用户在textBox中输入内容时我的new personName被设置为什么。因此,用户在listBox中选择其中一个ItemTemplate对象,此项目具有用户单击的组合框和其他UI控件。当用户点击其中一个UI控件时,某些数据会发生变化。

我尝试了((Resident)MyList.SelectedItem).personName和其他一些方法,看看我是否可以访问数据并对其进行操作。现在有趣的是,我在ItemTemplate中的comboBox有一个选择更改事件,当选择被更改时调用,但我无法访问数据!

提前致谢!

2 个答案:

答案 0 :(得分:1)

有多种方法可以满足您的需求。最简单的方法是在ViewModel上放置SelectedItem属性。

你的VieWModel就像这样......

public class MyViewModel : INotifyPropertyChanged
{
      ObservableCollection<Resident> Residents { get; }

      private Resident _selectedItem;
      public Resident SelectedItem
      {
           get { return _selectedItem; }
           set
           {
                _selectedItem = value;
                PropertyChangedEventHandler handler = PropertyChanged;
                if(handler != null)
                    handler(this, new PropertyChangedEventArgs("SelectedItem");
           }
      }
}

在您的视图中,将DataContext设置为此ViewModel的实例,其中ListBox.ItemsSource绑定到ResidentsListBox.SelectedItem绑定到SelectedItem {1}}。

<ListBox ItemsSource="{Binding Path=Residents}" 
         SelectedItem="{Binding Path=Selectedtem, Mode=TwoWay}" />

如果您想在选择更改时执行操作,请记下SelectedItem属性的设置者,该属性将包含新选择的项目。

修改

注意到您的Resident模型没有实现INotifyPropertyChanged,它需要做的是向下传播更改。然后,您可以获得数据在给定属性的setter中更改的点,如SelectedItem属性所述。

答案 1 :(得分:0)

下面的示例使用ViewModel(VM)。如果您向Residents集合添加新居民,他们将显示在列表框中。只是一个提示,如果你最终命名控件很多,你没有正确地进行数据绑定。

XAML:

<ListBox ItemsSource="{Binding Path=Residents}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <TextBlock Text="{Binding Path=PersonName}" />
                <ComboBox 
                    ItemsSource="{Binding Path=DataContext.ListOfNums, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}}" 
                    SelectionChanged="NumberOfRes_SelectionChanged" />
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

代码背后:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        DataContext = new VM();
    }

    private void NumberOfRes_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
    {
        ComboBox comboBox = sender as ComboBox;
        Resident resident = comboBox.DataContext as Resident;
        int number = (int)comboBox.SelectedItem;
    }
}

public class VM
{
    public VM()
    {
        Residents = new ObservableCollection<Resident>() { new Resident() { PersonName = "AAA" }, new Resident() { PersonName = "BBB" } };
    }

    public ObservableCollection<Resident> Residents { get; private set; }

    public IEnumerable<int> ListOfNums
    {
        get { return new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8 }; }
    }
}

public class Resident
{
    public string PersonName { get; set; }
}