使用绑定禁用特定DataGrid单元格

时间:2013-04-17 15:03:31

标签: c# wpf xaml data-binding datagrid

我正在尝试将自定义数据对象列表绑定到数据网格,并实现以下行为。

  1. 填充网格
  2. 根据对象数据禁用某些单元格。
  3. 考虑以下DataGrid

    <DataGrid ItemsSource="{Binding Path=CustomObjectList}">
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding Path=FieldName}"
                                Header="Field Name"
                                IsReadOnly="True" />
            <DataGridCheckBoxColumn Binding="{Binding Path=Compare}"
                                    Header="Compare" />
            <DataGridTextColumn Binding="{Binding Path=Tolerance}"
                                Header="Tolerance" />
        </DataGrid.Columns>
    </DataGrid>
    

    使用这样的支持对象......

    public class CustomObject: BaseModel
    {
        private bool _compare;
    
        private bool _disableTolerance;
    
        private string _fieldName;
    
        private bool _mustCompare;
    
        private double _tolerance;
    
        /// <summary>
        /// Gets or sets the compare.
        /// </summary>
        /// <value>The compare.</value>
        public bool Compare
        {
            get
            {
                return this._compare;
            }
            set
            {
                this._compare = value;
                this.NotifyPropertyChange("Compare");
            }
        }
    
        /// <summary>
        /// Gets or sets the disable tolerance.
        /// </summary>
        /// <value>The disable tolerance.</value>
        public bool DisableTolerance
        {
            get
            {
                return this._disableTolerance;
            }
            set
            {
                this._disableTolerance = value;
                this.NotifyPropertyChange("DisableTolerance");
            }
        }
    
        /// <summary>
        /// Gets or sets the name of the field.
        /// </summary>
        /// <value>The name of the field.</value>
        public string FieldName
        {
            get
            {
                return this._fieldName;
            }
            set
            {
                this._fieldName = value;
                this.NotifyPropertyChange("FieldName");
            }
        }
    
        /// <summary>
        /// Gets or sets the must compare.
        /// </summary>
        /// <value>The must compare.</value>
        public bool MustCompare
        {
            get
            {
                return this._mustCompare;
            }
            set
            {
                this._mustCompare = value;
                this.NotifyPropertyChange("MustCompare");
            }
        }
    
        /// <summary>
        /// Gets or sets the tolerance.
        /// </summary>
        /// <value>The tolerance.</value>
        public double Tolerance
        {
            get
            {
                return this._tolerance;
            }
            set
            {
                this._tolerance = value;
                this.NotifyPropertyChange("Tolerance");
            }
        }
    }
    

    你可以考虑像这样填充CustomObjectList ......

    this.ComparisonsAndTolerances.Add(new ComparisonSettingsTolerances()
    {
        FieldName = "Alpha",
        Compare = true,
        MustCompare = true,
        Tolerance = 0,
        DisableTolerance = false
    });
    
    this.ComparisonsAndTolerances.Add(new ComparisonSettingsTolerances()
    {
        FieldName = "Bravo",
        Compare = true,
        MustCompare = false,
        Tolerance = 0,
        DisableTolerance = true
    });
    

    因此,FieldName,Compare和Tolerance属性当然会正确地填充到网格中。

    但是,我想要实现的是,当MustCompare为真时,该单元格被标记为只读。当DisableTolerance为true时,该单元格被标记为只读。

    显然,这将因细胞与细胞和行与行的不同而有所不同,但我希望通过绑定实现这一目标。

    我试过

    IsReadOnly="{Binding Path=MustCompare}"
    

    IsReadOnly="{Binding Path=CustomObjectList/MustCompare}"
    

    但这些都没有奏效。

    感谢。

1 个答案:

答案 0 :(得分:6)

这是你遇到的一个有趣的错误/情况。

会发生什么?好吧,绑定试图绑定到MustCompare属性(并且可能会成功)但它找不到FrameworkElementFrameworkContentElement作为绑定的目标,因为没有数据网格的列在视觉树中。

有一种解决方案,尽管不如你(正当地)试图做的那么优雅:

<DataGridTemplateColumn Header="Compare">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock x:Name="TextHolder" />
            <DataTemplate.Triggers>
                <DataTrigger Binding="{Binding Path=Compare}"
                             Value="True">
                    <Setter TargetName="TextHolder"
                            Property="Text"
                            Value="True" />
                </DataTrigger>
                <DataTrigger Binding="{Binding Path=Compare}"
                             Value="False">
                    <Setter TargetName="TextHolder"
                            Property="Text"
                            Value="False" />
                </DataTrigger>
            </DataTemplate.Triggers>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
    <DataGridTemplateColumn.CellEditingTemplate>
        <DataTemplate>
            <CheckBox x:Name="Check"
                      IsChecked="{Binding Path=Compare}"
                      ToolTipService.ShowOnDisabled="True"/>
            <DataTemplate.Triggers>
                <DataTrigger Binding="{Binding Path=MustCompare}"
                             Value="True">
                    <Setter TargetName="Check"
                            Property="IsEnabled"
                            Value="False" />
                    <Setter TargetName="Check"
                            Property="ToolTip"
                            Value="You cannot change this value since this item must compare" />
                </DataTrigger>
            </DataTemplate.Triggers>
        </DataTemplate>
    </DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>

我已经更改了单元格,因此它在非编辑模式下显示文本,在编辑时显示复选框(只是为了查看单元格的状态,在两种情况下都可以将其更改为复选框)。

这不是最佳选择,如果您(或任何人)找到更好的解决方案,我想听听您的意见。

编辑:

另一种解决方案的想法:

<DataGridCheckBoxColumn Binding="{Binding Path=Compare}"
                        Header="Compare">
    <DataGridCheckBoxColumn.CellStyle>
        <Style TargetType="{x:Type DataGridCell}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding MustCompare}"
                             Value="True">
                    <Setter Property="IsEnabled"
                            Value="False" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </DataGridCheckBoxColumn.CellStyle>
</DataGridCheckBoxColumn>

这使得在非编辑模式下禁用复选框,因此它看起来不同。根据您的功能设计,可能是好事还是坏事。