将ObservableCollection绑定到DataGrid ComboBox?

时间:2017-01-08 06:31:11

标签: c# wpf xaml combobox datagrid

我正在尝试使用ObservableCollection绑定ComboBox的项目,我已成功将它们绑定到StaticResource

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>

代码背后,

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);
           }
        }
    }

现在查找问题代码,

我发现很难在我做错的事情上调试XAML。

这是背后的代码,

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();
               }
           }
}

我无法展示我试图让XAML工作的多种方式,但我会发布我认为最接近它的工作方式,

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>

我需要添加什么才能正确绑定?

2 个答案:

答案 0 :(得分:2)

WPF中的绑定使用当前上下文的DataContext。在您的情况下,DataContext属于您的MainWindow,并且知道您在一个上下文中不能拥有其中两个,例如您可以在DataGrid内声明另一个但是您不能再使用MainWindow中的那个。 简而言之,您无法在同一上下文中绑定Nursing_Home_NameNursingHomeNames

那么解决方案是什么?

您必须将其中一个属性带到其他上下文。将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");
        }
    }
}

如果您实施GetNursingHomeNameFromDBSaveNursingHomeName

,这将有效

最后一个提示:ObservableCollection<T>不需要内置NotifyPropertyChanged()

答案 1 :(得分:1)

  

我需要添加什么才能正确绑定?

由于NursingHomeNames是父窗口的属性,而ComboBox的DataContext是DataGrid的ItemsSource集合中的项目,因此您需要将窗口指定为绑定的源。试试这个:

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