首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WPF DataGrid与DataGrid在RowDetailsTemplate中

WPF DataGrid与DataGrid在RowDetailsTemplate中
EN

Stack Overflow用户
提问于 2013-09-24 16:16:00
回答 1查看 3.8K关注 0票数 1

我上一篇关于在VM中检测属性更改的文章不够深入,所以我发布了以下文章

我有一个乔布斯的网格。每个工作可以有一个或多个雇员。

DataGrid的RowDetailsTemplate包含另一个显示员工的网格。因此,父网格被绑定到乔布斯列表中。内部网格绑定到“职务”模型中的员工列表。

工作模式:

代码语言:javascript
复制
public class Job : _Base
{
    private string _JobName = string.Empty;
    public string JobName
    {
        get { return _JobName; }
        set 
        {
            if (_JobName != value)
            {
                _JobName = value;
                RaisePropertyChanged("JobName");
            }
        }
    }

    private string _JobNumber = string.Empty;
    public string JobNumber
    {
        get { return _JobNumber; }
        set
        {
            if (_JobNumber != value)
            {
                _JobNumber = value;
                RaisePropertyChanged("JobNumber");
            }
        }
    }

    private ObservableCollection<Employee> _Employees;
    public ObservableCollection<Employee> Employees
    {
        get { return _Employees; }
        set
        {
            if (_Employees != value)
            {
                if (_Employees != value)
                {
                    _Employees = value;
                    RaisePropertyChanged("Employees");
                }
            }
        }
    }

    private Employee _SelectedEmployee;
    public Employee SelectedEmployee
    {
        get { return _SelectedEmployee; }
        set
        {
            if (_SelectedEmployee != value)
            {
                if (_SelectedEmployee != value)
                {
                    _SelectedEmployee = value;
                    RaisePropertyChanged("SelectedEmployee");
                }
            }
        }
    }

    public Job()
    {
        Employees = new ObservableCollection<Employee>();
    }
}

员工模型

代码语言:javascript
复制
public class Employee : _Base
{
    private string _EmployeeName = string.Empty;
    public string EmployeeName
    {
        get { return _EmployeeName; }
        set
        {
            if (_EmployeeName != value)
            {
                _EmployeeName = value;
                RaisePropertyChanged("EmployeeName");
            }
        }
    }

    private bool _IsChecked = false;
    public bool IsChecked
    {
        get { return _IsChecked; }
        set
        {
            if (_IsChecked != value)
            {
                _IsChecked = value;
                RaisePropertyChanged("IsChecked");
            }
        }
    }
}        

XAML

代码语言:javascript
复制
<DataGrid ItemsSource="{Binding Jobs}"
            SelectedItem="{Binding SelectedJob}"
            AutoGenerateColumns="False">

    <DataGrid.Columns>
        <DataGridTextColumn Header="Job Name" Binding="{Binding JobName}" />
        <DataGridTextColumn Header="Job Number" Binding="{Binding JobNumber}" />
    </DataGrid.Columns>

    <DataGrid.RowDetailsTemplate>
        <DataTemplate>

            <StackPanel Orientation="Vertical">

                <DataGrid ItemsSource="{Binding Employees}"
                            SelectedItem="{Binding SelectedEmployee}"
                            AutoGenerateColumns="False">

                    <DataGrid.Columns>
                        <DataGridCheckBoxColumn Binding="{Binding IsChecked}"/>
                        <DataGridTextColumn Binding="{Binding EmployeeName}"/>
                    </DataGrid.Columns>

                </DataGrid>

                <Button Margin="5"
                        Height="23"
                        Width="75"
                        HorizontalAlignment="Left"
                        Content="Remove"/>

            </StackPanel>


        </DataTemplate>
    </DataGrid.RowDetailsTemplate>

</DataGrid>

The MainWindowViewModel

代码语言:javascript
复制
public class MainWindowViewModel : _Base
{
    private ObservableCollection<Job> _Jobs;
    public ObservableCollection<Job> Jobs
    {
        get { return _Jobs; }
        set 
        {
            if (_Jobs != value)
            {
                if (_Jobs != value)
                {
                    _Jobs = value;
                    RaisePropertyChanged("Jobs");
                }
            }
        }
    }

    private Job _SelectedJob;
    public Job SelectedJob
    {
        get { return _SelectedJob; }
        set
        {
            if (_SelectedJob != value)
            {
                if (_SelectedJob != value)
                {
                    _SelectedJob = value;
                    RaisePropertyChanged("SelectedJob");
                }
            }
        }
    }

    public MainWindowViewModel()
    {
        this.PropertyChanged += new PropertyChangedEventHandler(MainWindowViewModel_PropertyChanged);
    }

    void MainWindowViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        if (e.PropertyName.Trim().ToLower() == "ischecked")
        {
            int x = 1;
        }
    }
}

我有几个问题:

1)当我单击内部网格中的员工时,作业模型上的SelectedEmployee属性不会触发。

2)当员工被选中时,MainWindowViewModel_PropertyChanged不会触发。

3)注意内部网格下方的按钮。如何将其命令绑定到MainWindowVM?

EN

回答 1

Stack Overflow用户

发布于 2013-09-24 17:38:46

  1. 因为有DataGridinside DataGrid's row,所以上面的DataGrid是eating up the selectionchange for the inner DataGrid。要解决这个问题,您需要强制更新子DataGrid的绑定源。为此,捕获内部DataGrid的DataGrid事件,并在处理程序中执行以下操作。 私有DataGrid_SelectionChanged(对象发送方,SelectionChangedEventArgs e) { DataGrid网格= e.OriginalSource as DataGrid;var表达式=SelectionChangedEventArgs expression.UpdateSource();}
  2. MainwindowVM没有任何ischecked属性,这就是为什么它的属性更改了,因为该属性没有触发。
  3. 要解决这个问题,你需要做几件事。问题是DataGrid单元格和行不继承DataContext,因为它们不属于它的可视树。因此,要解决这个问题,您必须使用BindingProxy将windows DataContext带到DataGrid行详细信息中的按钮。

定义绑定代理类如下:

代码语言:javascript
复制
    public class MyBindingProxy : Freezable
    {
        public static readonly DependencyProperty BindingDataProperty =
            DependencyProperty.Register("BindingData", typeof(object),
            typeof(MyBindingProxy), new UIPropertyMetadata(null));

        protected override Freezable CreateInstanceCore()
        {
            return new MyBindingProxy();
        }

        public object BindingData
        {
            get { return (object)GetValue(BindingDataProperty); }
            set { SetValue(BindingDataProperty, value); }
        }

    }

现在,在您的窗口的资源中(其中有DataGrid ),创建代理实例,并将BindingData设置为窗口的DataContext,即MainWindowViewModel,如:

代码语言:javascript
复制
<Window.Resources>
    <local:MyBindingProxy x:Key="myproxy" BindingData="{Binding}" />
</Window.Resources>

现在,只需在按钮上设置如下命令:

代码语言:javascript
复制
<Button Margin="5"
   Height="23"
   Width="75"
   HorizontalAlignment="Left"
   Content="Remove"
   Command="{Binding BindingData.MyCommand, Source={StaticResource myproxy}}"/>
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18986848

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档