Reputation: 2741
I am trying to bind the items of the ComboBox with an ObservableCollection, I have been successfully binding them to a StaticResource
,
The XAML, Nursing_Home_Name
is the SQL Server Table and this code works fine for me.
<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.
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,
The XAML, Nursing_Home_Name
is the SQL Server Table 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?
Upvotes: 0
Views: 1134
Reputation: 169200
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. Try this:
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding Path=NursingHomeNames, RelativeSource={RelativeSource AncestorType=Window}}"
SelectedItem="{Binding Path=Nursing_Home_Name}"/>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
Upvotes: 1
Reputation: 3929
Binding in WPF uses what's called the DataContext
of current context. 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.
In short you can't bind to Nursing_Home_Name
and NursingHomeNames
in the same context.
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:
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
.
One final tip: ObservableCollection<T>
doesn't require NotifyPropertyChanged()
it's built in.
Upvotes: 2