C# 将ObservableCollection绑定到组合框

C# 将ObservableCollection绑定到组合框,c#,wpf,xaml,data-binding,combobox,C#,Wpf,Xaml,Data Binding,Combobox,我正在尝试将一个可观察集合(C#)绑定到一个组合框(XAML)。互联网上的一百万篇文章、问题/答案和帖子表明,这是一项非常简单的任务。到目前为止,我不同意他们的观点: XAML <Window x:Class = "ComboTest.MainWindow" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schem

我正在尝试将一个
可观察集合
(C#)绑定到一个
组合框
(XAML)。互联网上的一百万篇文章、问题/答案和帖子表明,这是一项非常简单的任务。到目前为止,我不同意他们的观点:

XAML

<Window
    x:Class     = "ComboTest.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"
    DataContext = "{Binding RelativeSource={RelativeSource Self}}">
    <StackPanel>
        <ComboBox 
            Name          = "URICombo"
            ItemsSource   = "{Binding URIs}" 
            SelectedIndex = "0">
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Name}"></TextBlock>
                </DataTemplate>
            </ComboBox.ItemTemplate>
        </ComboBox>
    </StackPanel>
</Window>

C#

名称空间组合测试
{
公共部分类主窗口:窗口
{
公共类配对
{
公共字符串URI{get;set;}
公共字符串名称{get;set;}
公共URI配对(字符串\u名称,字符串\u URI)
{
this.Name=\u Name;
this.URI=\u URI;
}
}
公共ObservableCollection URI{get;set;}
公共主窗口()
{
初始化组件();
DataContext=this;
this.URIs=new System.Collections.ObjectModel.ObservableCollection();
Add(新的uripaining(“DEV”,“someurl”);
Add(新的uripaining(“沙盒”,“一些URL”);
Add(新的uripaling(“QA”,“someuri”);
}
}
}
运行时,应用程序会显示一个简单的空组合框。

调试表明,
ObservaleCollection
已正确填充,查看Visual Studio的“应用数据绑定…”面板,我可以看到DataContext为null,并且没有可绑定的路径


我真诚地希望我没有犯一些愚蠢的拼写错误(我已经复制/粘贴了我能找到的所有相似的名称空间,但运气不好);但是,我完全不知所措。

您错过了分配给组合框的主要部分

        this.URIs = new stem.Collections.ObjectModel.ObservableCollection<URIPairing>();
         this.URIs.Add(new URIPairing("DEV", "Some URL"));
        this.URIs.Add(new URIPairing("SANDBOX", "Some URL"));
        this.URIs.Add(new URIPairing("QA", "Some URI"));
        URICombo.ItemsSource = URIs;
        URICombo.DisplayMemberPath = "Name";
this.URIs=new stem.Collections.ObjectModel.ObservableCollection();
Add(新的uripaining(“DEV”,“someurl”);
Add(新的uripaining(“沙盒”,“一些URL”);
Add(新的uripaling(“QA”,“someuri”);
URICombo.ItemsSource=URI;
URICombo.DisplayMemberPath=“Name”;

您错过了分配给组合框的主要部分

        this.URIs = new stem.Collections.ObjectModel.ObservableCollection<URIPairing>();
         this.URIs.Add(new URIPairing("DEV", "Some URL"));
        this.URIs.Add(new URIPairing("SANDBOX", "Some URL"));
        this.URIs.Add(new URIPairing("QA", "Some URI"));
        URICombo.ItemsSource = URIs;
        URICombo.DisplayMemberPath = "Name";
this.URIs=new stem.Collections.ObjectModel.ObservableCollection();
Add(新的uripaining(“DEV”,“someurl”);
Add(新的uripaining(“沙盒”,“一些URL”);
Add(新的uripaling(“QA”,“someuri”);
URICombo.ItemsSource=URI;
URICombo.DisplayMemberPath=“Name”;

您忘记将
DataContext
设置为自身:

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

可以是XAML格式:

<Window DataContext="{Binding RelativeSource={RelativeSource Self}}"/>

您忘记将
DataContext
设置为自身:

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

可以是XAML格式:

<Window DataContext="{Binding RelativeSource={RelativeSource Self}}"/>

无法工作的原因是您没有在
主窗口中实现
INotifyPropertyChanged
。当您将
DataContext
绑定到窗口上的
relativesourceself
时,最初,当您运行应用程序时,它试图获取尚未设置的
uri
属性,然后您将构造函数中的
DataContext
重置为
this
,这会将其标记为新的,并且已经很晚了,因此您需要调用
INPC

一个简单而干净的修复方法是删除构造函数中的
DataContext
设置或
XAML
中的绑定,但不能同时删除这两个设置

public partial class MainWindow : Window, INotifyPropertyChanged
{
    // Implementation of the INPC
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        var handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }

    public class URIPairing
    {
        public string URI  { get; set; }
        public string Name { get; set; }

        public URIPairing(string _Name, string _URI)
        {
            this.Name = _Name;
            this.URI  = _URI;
        }
    }
    private ObservableCollection<URIPairing> _uris;
    public ObservableCollection<URIPairing> URIs { get { return _uris; } set { _uris = value; OnPropertyChanged(); } }

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

        this.URIs = new System.Collections.ObjectModel.ObservableCollection<URIPairing>();
        this.URIs.Add(new URIPairing( "DEV"     , "Some URL" ));
        this.URIs.Add(new URIPairing( "SANDBOX" , "Some URL" ));
        this.URIs.Add(new URIPairing( "QA"      , "Some URI" ));
    }
}
public分部类主窗口:窗口,INotifyPropertyChanged
{
//INPC的实施
受保护的虚拟void OnPropertyChanged([CallerMemberName]字符串propertyName=null)
{
var handler=PropertyChanged;
if(handler!=null)handler(这是新的PropertyChangedEventArgs(propertyName));
}
公共类配对
{
公共字符串URI{get;set;}
公共字符串名称{get;set;}
公共URI配对(字符串\u名称,字符串\u URI)
{
this.Name=\u Name;
this.URI=\u URI;
}
}
私人可观察收集(uri);;
公共ObservableCollection URI{get{return{uURI;}set{uURI=value;OnPropertyChanged();}}
公共主窗口()
{
初始化组件();
DataContext=this;
this.URIs=new System.Collections.ObjectModel.ObservableCollection();
Add(新的uripaining(“DEV”,“someurl”);
Add(新的uripaining(“沙盒”,“一些URL”);
Add(新的uripaling(“QA”,“someuri”);
}
}

这会将新值传播到
用户界面

不起作用的原因是您在
主窗口
中未实现
INotifyPropertyChanged
。当您将
DataContext
绑定到窗口上的
relativesourceself
时,最初,当您运行应用程序时,它试图获取尚未设置的
uri
属性,然后您将构造函数中的
DataContext
重置为
this
,这会将其标记为新的,并且已经很晚了,因此您需要调用
INPC

一个简单而干净的修复方法是删除构造函数中的
DataContext
设置或
XAML
中的绑定,但不能同时删除这两个设置

public partial class MainWindow : Window, INotifyPropertyChanged
{
    // Implementation of the INPC
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        var handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }

    public class URIPairing
    {
        public string URI  { get; set; }
        public string Name { get; set; }

        public URIPairing(string _Name, string _URI)
        {
            this.Name = _Name;
            this.URI  = _URI;
        }
    }
    private ObservableCollection<URIPairing> _uris;
    public ObservableCollection<URIPairing> URIs { get { return _uris; } set { _uris = value; OnPropertyChanged(); } }

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

        this.URIs = new System.Collections.ObjectModel.ObservableCollection<URIPairing>();
        this.URIs.Add(new URIPairing( "DEV"     , "Some URL" ));
        this.URIs.Add(new URIPairing( "SANDBOX" , "Some URL" ));
        this.URIs.Add(new URIPairing( "QA"      , "Some URI" ));
    }
}
public分部类主窗口:窗口,INotifyPropertyChanged
{
//INPC的实施
受保护的虚拟void OnPropertyChanged([CallerMemberName]字符串propertyName=null)
{
var handler=PropertyChanged;
if(handler!=null)handler(这是新的PropertyChangedEventArgs(propertyName));
}
公共类配对
{
公共字符串URI{get;set;}
公共字符串名称{get;set;}
公共配对(字符串_名称,字符串_