【发布时间】:2011-07-27 22:18:52
【问题描述】:
我查看了variousquestions 的答案,但没有设法将答案中的内容映射到我试图解决的问题。我已将其缩减为以下代码(代表我试图实现的结果),并且基本上希望能够在未编辑行时将Person.TitleId 呈现为其对应的Title.TitleText,并正确绑定下拉列表,以便在下拉列表中显示TitleTexts,并在更改时将关联的TitleId 写回Person 记录。
简而言之,我在<DataGridComboBoxColumn> 中输入了什么来实现这一点?
App.xaml.cs
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
var viewModel = new ViewModels.MainWindowViewModel();
var mainWindow = new MainWindow();
mainWindow.DataContext = viewModel;
mainWindow.ShowDialog();
}
MainWindow.xaml
<Grid>
<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Path=Contacts}">
<DataGrid.Columns>
<DataGridComboBoxColumn Header="Title" SelectedItemBinding="{Binding Person}">
<DataGridComboBoxColumn.ElementStyle>
<Style TargetType="ComboBox">
<Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.Titles}"/>
<Setter Property="IsReadOnly" Value="True"/>
</Style>
</DataGridComboBoxColumn.ElementStyle>
<DataGridComboBoxColumn.EditingElementStyle>
<Style TargetType="ComboBox">
<Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.Titles}"/>
<Setter Property="DisplayMemberPath" Value="TitleText" />
</Style>
</DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
Person.cs
public class Person
{
public int TitleId { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
}
Title.cs
public struct Title
{
public Title(int titleId, string titleText)
: this()
{
TitleId = titleId;
TitleText = titleText;
}
public string TitleText { get; private set; }
public int TitleId { get; private set; }
public static List<Title> GetAvailableTitles()
{
var titles = new List<Title>();
titles.Add(new Title(1, "Mr"));
titles.Add(new Title(2, "Miss"));
titles.Add(new Title(3, "Mrs"));
return titles;
}
}
MainWindowViewModel.cs
public class MainWindowViewModel : ViewModelBase
{
private ObservableCollection<Person> contacts;
private List<Title> titles;
public MainWindowViewModel()
{
titles = Title.GetAvailableTitles();
Contacts = new ObservableCollection<Person>();
Contacts.Add(new Person() { FirstName = "Jane", LastName = "Smith", TitleId = 2 });
}
public List<Title> Titles
{
get { return titles; }
}
public ObservableCollection<Person> Contacts
{
get { return contacts; }
set
{
if (contacts != value)
{
contacts = value;
this.OnPropertyChanged("Contacts");
}
}
}
}
ViewModelBase.cs
public class ViewModelBase : INotifyPropertyChanged
{
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
【问题讨论】:
-
如果您能概述该“计划”的哪些部分不起作用/哪些部分实际起作用,这将有所帮助。例如你能找到 ComboBox 的 ItemsSource 列表吗?
-
另外:从您使用
Title的方式来看,该类似乎是多余的,最好用Dictionary<int,string>代替。 -
@H.B. - 正如代码所示,网格不显示初始值的文本表示(即 Person.TitleId 的适当 TitleText),下拉列表会正确填充 {Mr,Mrs,Miss} 并在下拉菜单导致 TestMVVM.Models.Title 显示在网格中(TestMVVM.Models 是解决方案中的命名空间,为简洁起见,我将其删除)。
-
@H.B. - “标题”是我的“真实”代码的简化。我已将 real 代码简化为这个示例案例(在我的“真实”代码中,Title 类具有更多属性,而我可以将其提炼为
Dictionary<int, string>网格,我宁愿不要,因为它的代码更多)看看我是否可以自己解决它而没有任何无关的问题,例如数据库访问。鉴于最小的情况是在stackoverflow上发布的最佳情况,这就是我所做的=) -
哦,抱歉,我没有意识到你已经压缩了它,因为它仍然有点大。
标签: wpf mvvm datagrid datagridcomboboxcolumn