简体   繁体   English

将ObservableCollection绑定到DataGrid ComboBox?

[英]Binding ObservableCollection to DataGrid ComboBox?

I am trying to bind the items of the ComboBox with an ObservableCollection, I have been successfully binding them to a StaticResource , 我试图将ComboBox的项目与ObservableCollection绑定,我已经成功将其绑定到StaticResource

The XAML, Nursing_Home_Name is the SQL Server Table and this code works fine for me. XAML Nursing_Home_Name是SQL Server表,此代码对我来说很好。

<Window.Resources>
    <local:CollectionsLists x:Key="StaticNursingHomeList" />
</Window.Resources>


<DataGridTemplateColumn Width="120" Header="施設名称">
   <DataGridTemplateColumn.CellTemplate>
      <DataTemplate>
         <TextBlock Text="{Binding UpdateSourceTrigger=PropertyChanged,
                           Path=Nursing_Home_Name}" />
      </DataTemplate>
   </DataGridTemplateColumn.CellTemplate>
   <DataGridTemplateColumn.CellEditingTemplate>
       <DataTemplate>
          <ComboBox Text="{Binding Path=Nursing_Home_Name,
                           UpdateSourceTrigger=PropertyChanged}"
                           ItemsSource="{Binding NursingHome, 
                           Source={StaticResource StaticNursingHomeList}}" />
       </DataTemplate>
    </DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>

And code behind, 和后面的代码

class CollectionsLists
    {     
        public static List<string> NursingHome { get; set; } 
        var homeNames = Database.GetNursingHomeNames(_nursingHomeSection);
        if (homeNames != null)
        {
           NursingHome = new List<string>();
           foreach (var item in homeNames)
           {
                NursingHome.Add(item);
           }
        }
    }

Now for the problem code, 现在对于问题代码,

I am finding it very hard to debug the XAML on what I am doing wrong. 我发现很难在我做错的事情上调试XAML。

This is the code behind, 这是背后的代码,

public partial class MainWindow : INotifyPropertyChanged
    {        
        public MainWindow()
        { 
            DataContext = this; 
            InitializeComponent();
        }

        private ObservableCollection<string> _nursingHomeNames = new ObservableCollection<string>();

        public ObservableCollection<string> NursingHomeNames
           {
               get { return _nursingHomeNames; }
               set
               {
                   _nursingHomeNames = value;
                   NotifyPropertyChanged();
               }
           }
}

And I cannot show the multitude of ways that I have tried to get the XAML to work, but instead I will post what I thought was the closest to getting it to work, 而且,我无法展示尝试使XAML正常工作的多种方法,但我会发布我认为最接近使其正常工作的内容,

The XAML, Nursing_Home_Name is the SQL Server Table BTW XAML Nursing_Home_Name是SQL Server表BTW

<DataGridTemplateColumn Width="120" Header="施設名称">
   <DataGridTemplateColumn.CellTemplate>
      <DataTemplate>
         <TextBlock Text="{Binding UpdateSourceTrigger=PropertyChanged,
                           Path=Nursing_Home_Name}" />
      </DataTemplate>
   </DataGridTemplateColumn.CellTemplate>
   <DataGridTemplateColumn.CellEditingTemplate>
       <DataTemplate>
          <ComboBox Text="{Binding Path=Nursing_Home_Name,
                           UpdateSourceTrigger=PropertyChanged}"
                           ItemsSource="{Binding NursingHomeNames}" />
       </DataTemplate>
    </DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>

What do I need to add to get this to bind correctly? 我需要添加什么才能使其正确绑定?

Binding in WPF uses what's called the DataContext of current context. WPF中的绑定使用当前上下文的DataContext In your case DataContext is of your MainWindow and know this that you can't have two of these in one context for example you can declare another one inside your DataGrid but you can't use the one from MainWindow any more. 在您的情况下, DataContext属于您的MainWindow并且知道您不能在一个上下文中拥有其中的两个,例如,您可以在DataGrid声明另一个,而您不能再使用MainWindow一个。 In short you can't bind to Nursing_Home_Name and NursingHomeNames in the same context. 简而言之,您不能在同一上下文中绑定Nursing_Home_NameNursingHomeNames

Ok what's the solution then? 好的,那有什么解决方案?

You have to bring one of these properties to the other context. 您必须将这些属性之一带入另一个上下文。 It's simpler to bring your Nursing_Home_Name to your MainWindow like this: 像这样将您的Nursing_Home_Name带到MainWindow更简单:

public partial class MainWindow : INotifyPropertyChanged
{        
    public MainWindow()
    { 
        DataContext = this; 
        InitializeComponent();
    }

    private ObservableCollection<string> _nursingHomeNames = new ObservableCollection<string>();

    public ObservableCollection<string> NursingHomeNames
       {
           get { return _nursingHomeNames; }
           set { _nursingHomeNames = value; }
       }

    public string Nursing_Home_Name //Unconventional name. But I kept your naming
    {
        get { return GetNursingHomeNameFromDB(); }
        set 
        {
            SaveNursingHomeName(value); 
            NotifyPropertyChanged("Nursing_Home_Name");
        }
    }
}

This will work if you implement GetNursingHomeNameFromDB and SaveNursingHomeName . 如果实现GetNursingHomeNameFromDBSaveNursingHomeName这将起作用。

One final tip: ObservableCollection<T> doesn't require NotifyPropertyChanged() it's built in. 最后一条提示: ObservableCollection<T>不需要它内置的NotifyPropertyChanged()

What do I need to add to get this to bind correctly? 我需要添加什么才能使其正确绑定?

Since NursingHomeNames is a property of the parent window and the DataContext of the ComboBox is an item in the ItemsSource collection of the DataGrid, you need to specify the window as the source of the binding. 由于NursingHomeNames是父窗口的属性,而ComboBox的DataContext是DataGrid的ItemsSource集合中的一项,因此需要将窗口指定为绑定的源。 Try this: 尝试这个:

<DataGridTemplateColumn.CellEditingTemplate>
    <DataTemplate>
        <ComboBox ItemsSource="{Binding Path=NursingHomeNames, RelativeSource={RelativeSource AncestorType=Window}}"
                          SelectedItem="{Binding Path=Nursing_Home_Name}"/>
    </DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM