C# MVVM、组合框绑定和DatagridTemplateColumn?
我有一个使用组合框的C# MVVM、组合框绑定和DatagridTemplateColumn?,c#,wpf,mvvm,combobox,datagrid,C#,Wpf,Mvvm,Combobox,Datagrid,我有一个使用组合框的DatagridTemplateColumn,但是ItemSource不会填充绑定的集合 private ObservableCollectionEx<StaffInfoDetail> _sectionStaffMasterDisplay = new ObservableCollectionEx<StaffInfoDetail>(); public ObservableCollectionEx<StaffInfoDetail>
DatagridTemplateColumn
,但是ItemSource
不会填充绑定的集合
private ObservableCollectionEx<StaffInfoDetail> _sectionStaffMasterDisplay = new ObservableCollectionEx<StaffInfoDetail>();
public ObservableCollectionEx<StaffInfoDetail> SectionStaffMasterDisplay
{
get { return _sectionStaffMasterDisplay; }
set
{
if (value != _sectionStaffMasterDisplay)
{
_sectionStaffMasterDisplay = value;
OnPropertyChanged();
}
}
}
我应该提到的是,DataGrid
正在正确绑定,并且veiwModel中的任何其他集合都在工作,只是DataGrid中的这个ComboBox
不起作用
这是MCVE示例代码:
<UserControl
d:DataContext="{d:DesignInstance d:Type=viewModels:StaffInfoDetailViewModel, IsDesignTimeCreatable=False}">
<DataGrid Grid.Column="0" Grid.ColumnSpan="6" AutoGenerateColumns="False" ItemsSource="{Binding SectionStaffMasterDisplay}" Grid.Row="4" Grid.RowSpan="2" AlternationCount="2" CanUserAddRows="True" CanUserDeleteRows="True" GridLinesVisibility="None" VerticalAlignment="Top" CanUserSortColumns="False">
<DataGridTemplateColumn Width="190" Header="資格">
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox
DisplayMemberPath="ItemName"
SelectedValuePath="ItemName"
SelectedItem="{Binding Path=Name, UpdateSourceTrigger=LostFocus}"
ItemsSource="{Binding Path=LicenceComboBox}" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
.....more XAML
模型类:
public partial class Licence
{
public System.Guid Id { get; set; } // ID (Primary key)
public string ItemName { get; set; } // ItemName (length: 50)
public string Section { get; set; } // Section (length: 50)
public Licence()
{
InitializePartial();
}
partial void InitializePartial();
}
datagrid集合
private ObservableCollectionEx<StaffInfoDetail> _sectionStaffMasterDisplay = new ObservableCollectionEx<StaffInfoDetail>();
public ObservableCollectionEx<StaffInfoDetail> SectionStaffMasterDisplay
{
get { return _sectionStaffMasterDisplay; }
set
{
if (value != _sectionStaffMasterDisplay)
{
_sectionStaffMasterDisplay = value;
OnPropertyChanged();
}
}
}
对于填充集合的方法,我将调用者添加到来自public staffinfo detailviewmodel()
的原始代码中:
我看不出DataContext
有什么问题,但为什么当其他所有属性都正常工作时,这个绑定就不能正确绑定呢
在代码中单步显示要正确填写的
许可证组合框
。我在这里看到组合框项源不是DataGrid项源的一部分。因此,它们都共享不同的数据上下文。
Combobox ItemsSource的DataContext是ViewModel,我假设ViewModel是datagrid的DataContext。如果我的假设是正确的,那么您需要将相对源添加到Combobox的ItemsSource绑定中
为此使用以下语法:
<ComboBox
DisplayMemberPath="ItemName"
SelectedValuePath="ItemName"
ItemsSource="{Binding Path=PathToProperty,
RelativeSource={RelativeSource AncestorType={x:Type typeOfAncestor}}}"
</ComboBox>
我在这里看到Combobox ItemsSource不是DataGrid ItemsSource的一部分。因此,它们都共享不同的数据上下文。 Combobox ItemsSource的DataContext是ViewModel,我假设ViewModel是datagrid的DataContext。如果我的假设是正确的,那么您需要将相对源添加到Combobox的ItemsSource绑定中 为此使用以下语法:
<ComboBox
DisplayMemberPath="ItemName"
SelectedValuePath="ItemName"
ItemsSource="{Binding Path=PathToProperty,
RelativeSource={RelativeSource AncestorType={x:Type typeOfAncestor}}}"
</ComboBox>
这个问题是关于数据上下文的。DataGrid
中的每一行都有自己的DataContext
——来自DataGrid.ItemsSource
的集合项
让我们有一个非常简单的例子
using System.Collections.ObjectModel;
using GalaSoft.MvvmLight;
namespace WpfApp4.ViewModel
{
public class MainViewModel : ViewModelBase
{
public MainViewModel()
{
BarCollection = new ObservableCollection<BarModel>
{
new BarModel { Id = 1, Name = "Bar 1", },
new BarModel { Id = 2, Name = "Bar 2", },
new BarModel { Id = 3, Name = "Bar 3", },
};
FooCollection = new ObservableCollection<FooViewModel>
{
new FooViewModel{ Id = 1, },
new FooViewModel{ Id = 2, },
new FooViewModel{ Id = 3, },
};
}
public ObservableCollection<BarModel> BarCollection { get; set; }
public ObservableCollection<FooViewModel> FooCollection { get; set; }
}
public class FooViewModel : ViewModelBase
{
private BarModel _bar;
public int Id { get; set; }
public BarModel Bar { get => _bar; set => Set( ref _bar, value ); }
}
public class BarModel
{
public int Id { get; set; }
public string Name { get; set; }
public override string ToString()
{
return Name;
}
}
}
通过声明一个CollectionViewSource
并将BarCollection
绑定到它,就完成了这个神奇的过程
<Window.Resources>
<CollectionViewSource
x:Key="BarCollectionSource"
Source="{Binding Path=BarCollection}"/>
</Window.Resources>
本期是关于DataContext
的。DataGrid
中的每一行都有自己的DataContext
——来自DataGrid.ItemsSource
的集合项
让我们有一个非常简单的例子
using System.Collections.ObjectModel;
using GalaSoft.MvvmLight;
namespace WpfApp4.ViewModel
{
public class MainViewModel : ViewModelBase
{
public MainViewModel()
{
BarCollection = new ObservableCollection<BarModel>
{
new BarModel { Id = 1, Name = "Bar 1", },
new BarModel { Id = 2, Name = "Bar 2", },
new BarModel { Id = 3, Name = "Bar 3", },
};
FooCollection = new ObservableCollection<FooViewModel>
{
new FooViewModel{ Id = 1, },
new FooViewModel{ Id = 2, },
new FooViewModel{ Id = 3, },
};
}
public ObservableCollection<BarModel> BarCollection { get; set; }
public ObservableCollection<FooViewModel> FooCollection { get; set; }
}
public class FooViewModel : ViewModelBase
{
private BarModel _bar;
public int Id { get; set; }
public BarModel Bar { get => _bar; set => Set( ref _bar, value ); }
}
public class BarModel
{
public int Id { get; set; }
public string Name { get; set; }
public override string ToString()
{
return Name;
}
}
}
通过声明一个CollectionViewSource
并将BarCollection
绑定到它,就完成了这个神奇的过程
<Window.Resources>
<CollectionViewSource
x:Key="BarCollectionSource"
Source="{Binding Path=BarCollection}"/>
</Window.Resources>
由于DataGrid
中ComboBox
的DataContext
是staffinfo-detail
对象,LicenceComboBox
属性属于staffinfo-detailviewmodel
类,因此需要使用RelativeSource
才能绑定到此属性
试试这个:
<DataGridTemplateColumn Width="190" Header="資格">
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox
DisplayMemberPath="ItemName"
SelectedValuePath="ItemName"
SelectedValue="{Binding Path=Licence, UpdateSourceTrigger=LostFocus}"
ItemsSource="{Binding Path=DataContext.LicenceComboBox, RelativeSource={RelativeSource AncestorType=DataGrid}}" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
由于DataGrid
中ComboBox
的DataContext
是staffinfo-detail
对象,并且LicenceComboBox
属性属于staffinfo-detailviewmodel
类,因此需要使用RelativeSource
才能绑定到此属性
试试这个:
<DataGridTemplateColumn Width="190" Header="資格">
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox
DisplayMemberPath="ItemName"
SelectedValuePath="ItemName"
SelectedValue="{Binding Path=Licence, UpdateSourceTrigger=LostFocus}"
ItemsSource="{Binding Path=DataContext.LicenceComboBox, RelativeSource={RelativeSource AncestorType=DataGrid}}" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
发布您的许可证
class@Max实体模型?B/c就是这样。首先编码。您要绑定到的Name属性在哪里?顺便说一句,SelectedItem将绑定所选的许可证实例。@SirRufo,添加了发布您的许可证
class@Max实体模型?B/c就是这样。请先编写代码。您要绑定到的Name属性在哪里?顺便说一句,SelectedItem将绑定所选的许可证实例。@SirRufo,AddedIt应该是“UserControl”,因为它是Datagrid的父级,VM附加到“UserControl”,而“UserControl”不做任何操作。还未填充。对于只包含代码片段的问题,没有人能提供准确答案。我们不得不猜太多的东西,我们可能猜错了。如果你想得到一个精确的答案,那就要问一个精确的问题。这个答案是正确的,和你的答案一样清楚question@SirRufo,所以我不能评论这个答案没有帮助?为什么要麻烦?我理解如何帮助人们,就像我通过Excel论坛和VBA在这里帮助许多人一样。我相信答案对你没有帮助,但这不是我的观点。这是正确的,和你的问题一样清楚。我没有说对你有什么帮助,它应该是“UserControl”,因为它是Datagrid的父级,VM附加到“UserControl”上,而“UserControl”不起任何作用。还未填充。对于只包含代码片段的问题,没有人能提供准确答案。我们不得不猜太多的东西,我们可能猜错了。如果你想得到一个精确的答案,那就要问一个精确的问题。这个答案是正确的,和你的答案一样清楚question@SirRufo,所以我不能评论这个答案没有帮助?为什么要麻烦?我理解如何帮助人们,就像我通过Excel论坛和VBA在这里帮助许多人一样。我相信答案对你没有帮助,但这不是我的观点。这是正确的,和你的问题一样清楚。我没说对你有什么帮助