WPF数据绑定到组合框
本文关键字:组合 数据绑定 WPF | 更新日期: 2023-09-27 17:53:07
我是WPF、c#和数据绑定的新手。我只是想绑定一个简单的组合框到一个ObservedCollection。下面是代码:
public class Directory
{
private string _ikey;
public string IKey
{
get
{
return _ikey;
}
set
{
_ikey = value;
}
}
private string _ivalue;
public string IValue
{
get
{
return _ivalue;
}
set
{
_ivalue = value;
}
}
}
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public ObservableCollection<Directory> DirectoryList = new ObservableCollection<Directory>();
public MainWindow()
{
InitializeComponent();
DirectoryList = new ObservableCollection<Directory>();
Directory _dirtemp = new Directory();
_dirtemp.IKey = "1";
_dirtemp.IValue = "Steve";
DirectoryList.Add(_dirtemp);
_dirtemp = new Directory();
_dirtemp.IKey = "2";
_dirtemp.IValue = "John";
DirectoryList.Add(_dirtemp);
}
}
我的xaml是这样的:
<Window x:Class="DataBindCombo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DataBindCombo"
Title="MainWindow" Height="350" Width="525">
<Grid>
<ComboBox Height="48" HorizontalAlignment="Left" Margin="70,104,0,0" Name="comboBox1" VerticalAlignment="Top" Width="310"
ItemsSource="{Binding Path=DirectoryList}"
DisplayMemberPath="IValue"
SelectedValuePath="IKey"
>
看起来应该很简单。我能够把绑定放在后面的代码中,它工作得很好,但我想让它通过xaml绑定。
任何想法?TIA
有几种方法可以做到这一点。最基本的是,您需要这样做,以便XAML可以看到您的集合。您可以通过将其设置为DataContext以隐式方式完成此操作。如果这是你唯一要绑定的东西,那么这是一种快速而肮脏的绑定方式。它看起来像这样:
public partial class MainWindow : Window
{
public ObservableCollection<Directory> DirectoryList;
public MainWindow()
{
InitializeComponent();
DirectoryList = new ObservableCollection<Directory>();
Directory _dirtemp = new Directory();
_dirtemp.IKey = "1";
_dirtemp.IValue = "Steve";
DirectoryList.Add(_dirtemp);
_dirtemp = new Directory();
_dirtemp.IKey = "2";
_dirtemp.IValue = "John";
DirectoryList.Add(_dirtemp);
DataContext=DirectoryList;
}
}
Window x:Class="DataBindCombo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DataBindCombo"
Title="MainWindow" Height="350" Width="525">
<Grid>
<ComboBox Height="48" HorizontalAlignment="Left" Margin="70,104,0,0" Name="comboBox1" VerticalAlignment="Top" Width="310"
ItemsSource="{Binding}"
DisplayMemberPath="IValue"
SelectedValuePath="IKey"
>
另一种方法更复杂,但可能你会更经常使用。要做到这一点,你需要在主窗口中公开你的集合作为DependencyProperty,然后绑定到该值。它看起来像这样:
public partial class MainWindow : Window
{
public static DependencyProperty DirectoryListProperty =
DependencyProperty.Register("DirectoryList",
typeof(ObservableCollection<Directory>),
typeof(MainWindow));
public MainWindow()
{
InitializeComponent();
}
public ObservableCollection<Directory> DirectoryList
{
get { return (ObservableCollection<Directory>)base.GetValue(DirectoryListProperty); }
set { base.SetValue(DirectoryListProperty, value); }
}
}
<Window x:Class="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" x:Name="mainWindow">
<Grid>
<ComboBox Height="48" HorizontalAlignment="Left" Margin="70,104,0,0" Name="comboBox1" VerticalAlignment="Top" Width="310"
ItemsSource=" {Binding ElementName=mainWindow, Path=DirectoryList}"
DisplayMemberPath="IValue"
SelectedValuePath="IKey"
/>
这也不是以这种方式完成它的唯一方法。一般来说,不是直接在控件上创建列表,而是创建视图模型。MVVM模式是创建演示文稿的推荐方式,但我的示例为您提供了一种实现功能的方法。你可以尝试不同的方法来做这件事。我发现在WPF中做事总是有多种方法,关键是找到最适合情况的方法。
绑定中的路径与本地DataContext有关,而不是与包含它的Window有关。你还没有为你的窗口设置一个DataContext,所以WPF没有一个对象来查找DirectoryList属性。
对于当前对象模型,您需要在MainWindow构造函数中设置this.DataContext = this;
。现在,MainWindow对象将是DataContext,而DirectoryList绑定将针对MainWindow对象进行解析。(从长远来看,更好的做法是将数据模型移到单独的类中,并将DataContext设置为该类的实例,但这是另一个问题。)
另外,WPF只能绑定属性,不能绑定字段。您的DirectoryList属性当前是一个字段;您需要将其更改为属性
你需要做的是设置ComboBox的DataContext等于你的ObservableCollection。
后台代码:
public partial class MainWindow : Window
{
private ObservableCollection<Directory> directoryList;
public MainWindow()
{
InitializeComponent();
directoryList = new ObservableCollection<Directory>();
Directory _dirtemp = new Directory();
_dirtemp.IKey = "1";
_dirtemp.IValue = "Steve";
directoryList.Add(_dirtemp);
_dirtemp = new Directory();
_dirtemp.IKey = "2";
_dirtemp.IValue = "John";
directoryList.Add(_dirtemp);
this.comboBox1.DataContext = DirectoryList;
//OR for the entire window you can simply do this.DataContext = DirectoryList;
}
public ObservableCollection<Directory> DirectoryList
{
get { return directoryList; }
}
}
public class Directory
{
private string _ikey;
public string IKey
{
get
{
return _ikey;
}
set
{
_ikey = value;
}
}
private string _ivalue;
public string IValue
{
get
{
return _ivalue;
}
set
{
_ivalue = value;
}
}
}
Xaml: <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="84" Width="167">
<Grid>
<ComboBox Height="23" HorizontalAlignment="Left" Margin="12,12,0,0" Name="comboBox1" VerticalAlignment="Top" Width="120" ItemsSource="{Binding}"/>
</Grid>
尽管,正如其他人所指出的,更好的方法是使用Model-View-ViewModel设计模式。这将使视图(xaml部分)与"业务逻辑"分开。下面是一个关于如何使用MVVM绑定组合框的好例子。
http://mark-dot-net.blogspot.com/2009/03/binding-combo-boxes-in-wpf-with-mvvm.html需要设置窗口的DataContext
。例如:
public MainWindow()
{
InitializeComponent();
DataContext = this;
....
}
将绑定指向后面的代码:
ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type Window}},Path=DirectoryList}"