【问题标题】:Databinding ComboBox to SelectedItem in DataGrid将 ComboBox 数据绑定到 DataGrid 中的 SelectedItem
【发布时间】:2011-11-21 19:15:42
【问题描述】:

我已经为我的问题寻找解决方案已经有一段时间了,所以现在我将在这里发布一些代码!

我正在使用 MVVM 处理我的应用程序中的数据,问题涉及以下两个 ViewModel 类

public class vmProject : vmBase
{
private Project project;


public User Owner
{
    get { return project.Owner; }
    set {project.Owner = value; OnPropertyChanged("Owner"); }
}


public vmProject(Project project)
{
    this.project = project;
}

}

public class User
{
public int Id { get; set; }
public string ShortName { get; set; }
public string FullName { get; set; }
}

我将所有项目加载到 ObservableCollection 中,并将所有用户加载到 ObservableCollection 中。 现在我想在 DataGrid 中显示所有项目,其中包含显示用户 ShortName 的 ComboBox。数据网格还应该有一个文本列,用于显示所有者的全名。

我的问题是,我不知道应该使用 DataGridComboBoxColumn 还是 DataGridTemplateColumn。以及如何在它们中的每一个中使用数据绑定......

当用户在组合框中选择新所有者时,模型以及 FullName 列应更新。

有什么解决办法吗?

【问题讨论】:

标签: wpf mvvm datagrid


【解决方案1】:

我不是 MVVM peron,但如果没有 MVVM,我会这样做。不要认为您需要 UsersFiltered 和 ObservableCollection。如果 UsersAll 是 Observable 集合,它会在您选择新名称时选择新行。

 bind the grid to a filtered list 


 public List<User> UsersFiltered 
 {
    get
    {
         return UsersAll.Where(usr => user = SelectedCBUser).ToList();
    }
 {

【讨论】:

    【解决方案2】:

    这是一个在模板列中使用组合框的示例。它假定您的 UserCollection 是包含 ProjectsCollection 的同一 DataContext 的一部分

    <DataGridColumn>
        <DataGridColumn.Template>
            <DataTemplate>
                <ComboBox ItemsSource="{Binding 
                              RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, 
                              Path=DataContext.UserCollection}"
                          SelectedValue="{Binding Owner}"
                          DisplayMemberPath="ShortName" />
            </DataTemplate>
        </DataGridColumn.Template>
    </DataGridColumn>
    

    当 WPF 比较 SelectedValue 的对象时,它通过引用比较它们。因此,除非每个 Property 上的 User 对象在内存中的引用与 UserCollection 中的引用完全相同,否则该值将返回 false 并且不会选择该项目。解决此问题的一种方法是使用User 类的overwrite the .ToString() method,因此如果它们的ID 字段匹配,则认为这些项目是相等的。

    另一种方法是使用 SelectedValuePath 并将 SelectedValue 绑定到通用数据类型,例如 int UserId 字段。

    <ComboBox ItemsSource="{Binding 
                   RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, 
                   Path=DataContext.UserCollection}"
              SelectedValue="{Binding Owner.Id}"
              SelectedValuePath="Id"
              DisplayMemberPath="ShortName" />
    

    【讨论】:

    • 我不确定上述解决方案是否能解决我的问题。为了更新 FullName 列,我认为我需要绑定 SelectedItem(而不是 SelectedValue)。我无法在 vmProject-object 中为所有者设置新的 ID,这不会更新实际的 Owner-User-object。还是我完全错了?
    • @ChristianTang 您可以使用SelectedItem,但请注意Owner 对象应引用UserCollection 中的项目才能使其工作,否则您需要覆盖ToString() 方法的User 类,因此如果它们的ID 相同,则认为这两个类相等。默认情况下,只有当它们引用内存中的相同对象时,它们才会被视为相等
    猜你喜欢
    • 2014-10-10
    • 2011-11-24
    • 2019-06-03
    • 1970-01-01
    • 2013-01-26
    • 2021-10-18
    • 2010-10-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多