【问题标题】:Disable Specific DataGrid Cells with Binding使用绑定禁用特定的 DataGrid 单元格
【发布时间】:2013-04-10 10:11:47
【问题描述】:

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

  1. 填充网格
  2. 根据对象数据禁用某些单元格。

考虑以下 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 时,该单元格被标记为只读。

显然,这会因 4 种不同组合而因单元格和行而异,但我希望通过绑定来实现。

我试过了

IsReadOnly="{Binding Path=MustCompare}"

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

但这些都不起作用。

谢谢。

【问题讨论】:

    标签: c# wpf xaml data-binding datagrid


    【解决方案1】:

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

    会发生什么?好吧,绑定正在尝试绑定到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>
    

    这使得复选框在非编辑模式下被禁用,因此看起来不同。可能是好事也可能是坏事,这取决于您的功能设计。

    【讨论】:

    • 您的“编辑”回复非常完美。谢谢。
    • 它有效,但我的问题是现在我无法选择任何行。
    猜你喜欢
    • 1970-01-01
    • 2017-07-25
    • 2011-12-12
    • 2013-11-03
    • 1970-01-01
    • 1970-01-01
    • 2017-11-29
    • 2016-11-04
    • 2010-10-24
    相关资源
    最近更新 更多