WPF数据绑定到组合框

时间:2011-04-26 00:30:37

标签: c# wpf data-binding

我是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

5 个答案:

答案 0 :(得分:3)

有几种方法可以解决这个问题。您需要完成基本操作,以便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"
              >

另一种方式更复杂,但可能更常用。要做到这一点您需要在MainWindow中将您的集合公开为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 pattern是创建演示文稿的推荐方式,但我的示例为您提供了一种获取功能的方法。您可以玩和尝试不同的方法来做到这一点。我发现在WPF中总有多种方法可以做到最好。

找到最适合这种情况的方法。

答案 1 :(得分:1)

绑定中的路径是关于本地DataContext,而不是包含Window。您尚未为Window设置DataContext,因此WPF没有可在其上查找DirectoryList属性的对象。

使用当前对象模型,您需要在MainWindow构造函数中设置this.DataContext = this;。现在,MainWindow对象将是DataContext,并且将针对MainWindow对象解析DirectoryList绑定。 (从长远来看,更好的做法是将数据模型移到单独的类中,并将DataContext设置为该类的实例,但这是一个单独的问题。)

此外,WPF只能绑定属性,而不能绑定字段。您的DirectoryList属性当前是一个字段;你需要把它改成一个属性。

答案 2 :(得分:1)

您需要做的是将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设计模式。这将使View(xaml部分)与“业务逻辑”分开。这是一个关于如何使用MVVM绑定comboBox的好例子。

http://mark-dot-net.blogspot.com/2009/03/binding-combo-boxes-in-wpf-with-mvvm.html

答案 3 :(得分:0)

您需要设置窗口的DataContext。例如:

public MainWindow()
{
    InitializeComponent();
    DataContext = this;
     ....
}

答案 4 :(得分:0)

将绑定指向您的代码:

ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type Window}},Path=DirectoryList}"