gpt4 book ai didi

c# - 如何防止 DataGridTemplateColumn 根据某些条件进入编辑模式?

转载 作者:行者123 更新时间:2023-12-02 22:09:34 26 4
gpt4 key购买 nike

我有一个可编辑的 DataGridTemplateColumn。如果业务对象满足某些条件,我只希望用户能够编辑此列中单元格的内容。假设我的业务对象实现了 INotifyPropertyChanged 并具有三个属性:NameDepartmentSalesNameDepartment 是字符串,Sales 是 double 。

我希望只有当 Department 等于“Retail”时,用户才能编辑 Sales 值。这是我可能用来执行此操作的数据网格:

<DataGrid ItemsSource="{Binding Path=MyTypeCollection}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Path=Name, Mode=OneTime}" IsReadOnly="True" />
<DataGridTextColumn Header="Department" Binding="{Binding Path=Department, Mode=OneTime}" IsReadOnly="True" />
<DataGridTemplateColumn Header="Sales">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=Sales, Mode=TwoWay}" Visibility="{Binding Path={StaticResource ResourceKey=IsRetail}}" />
<TextBlock Text="{Binding Path=Sales, Mode=OneWay}" Visibility="{Binding Path={StaticResource ResourceKey=IsNotRetail}}" />
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<StackPanel>
<TextBox Text="{Binding Path=Sales, Mode=TwoWay}" Visibility="{Binding Path={StaticResource ResourceKey=IsRetail}}" />
<TextBlock Text="{Binding Path=Sales, Mode=OneWay}" Visibility="{Binding Path={StaticResource ResourceKey=IsNotRetail}}" />
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>

我正在使用带有两个文本元素的堆栈面板。我在文本元素的可见性中使用绑定(bind)来切换文本元素。如果我有一行的 Department 值不是“Retail”,我会在 Sales 列中显示一个 TextBlock,无论该单元格是处于显示模式还是编辑模式。

这对我来说似乎是一个笨拙的解决方案。有什么方法可以阻止这些类型的单元格完全进入编辑模式吗?我只想在 Department 是“Retail”的情况下允许编辑模式。这可能吗?

编辑:添加代码。

@雷切尔。感谢您的帮助。我想粘贴我所有的数据网格 XAML 代码以确保一切正确。

<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Path=Data}">

<DataGrid.Resources>
<DataTemplate x:Key="TextBoxTemplate">
<TextBox Text="{Binding Path=Sales}" />
</DataTemplate>
</DataGrid.Resources>

<DataGrid.Columns>
<DataGridTextColumn Header="Department" Binding="{Binding Path=Department, Mode=OneTime}" />
<DataGridTextColumn Header="Name" Binding="{Binding Path=Name, Mode=OneTime}" />

<DataGridTemplateColumn>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ContentControl x:Name="salesControl">
<TextBlock Text="{Binding Sales}" />
</ContentControl>

<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Department}" Value="Retail">
<Setter TargetName="salesControl" Property="ContentTemplate" Value="{StaticResource TextBoxTemplate}" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>

<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Sales}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

</DataGrid.Columns>
</DataGrid>

我几乎已经把它拿到了我想要的地方。当我单击 Retail 行中的 Sales 值时,会出现一个 TextBox 但其中没有值(请参阅 here )。我不确定为什么它没有值,因为 TextBoxTemplate 中的 TextBox 指定了一个绑定(bind)。你知道这是为什么吗?

编辑:我注意到此解决方案的另一个问题,我实际上无法编辑“销售额”列中的值。如果我尝试,该值将恢复为原始的预编辑值。

最佳答案

我会使用 DataTrigger,它根据 Department 是否等于“Retail”来切换 TextBox.IsReadOnly 等属性的值

<Style ...>
<!-- Set Default -->
<Setter Property="IsReadOnly" Value="True" />

<Style.Triggers>
<DataTrigger Binding="{Binding Department}" Value="Retail">
<Setter Property="IsReadOnly" Value="False" />
</DataTrigger>
</Style.Triggers>
</Style>

如果您不需要在 DataGrid 中进行任何其他编辑,最简单的方法是在 DataGrid 上设置 IsReadOnly="True" 以完全禁用编辑,并且在 DataGridTemplateColumn 中的 TextBox 上设置此样式。这将摆脱很多额外的 XAML 代码,例如 IsReadOnly="True"

<DataGrid ItemsSource="{Binding Path=MyTypeCollection}" 
AutoGenerateColumns="False"
IsReadOnly="True">

<!-- This could also go in Window.Resources, UserControl.Resources, etc -->
<DataGrid.Resources>
<Style x:Key="SalesTextBoxStyle" TargetType="{x:Type TextBox}">
<!-- Set Default -->
<Setter Property="IsReadOnly" Value="True" />

<Style.Triggers>
<DataTrigger Binding="{Binding Department}" Value="Retail">
<Setter Property="IsReadOnly" Value="False" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.Resources>

<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Path=Name}"/>
<DataGridTextColumn Header="Department" Binding="{Binding Path=Department}" />
<DataGridTemplateColumn Header="Sales">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding Path=Sales}"
Style="{StaticResource SalesTextBoxStyle}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>

如果您确实需要默认的 DataGrid 编辑功能,您仍然可以使用相同的功能,但您只需要在 中使用一个 TextBox/TextBlock >DataTemplate 而不是 StackPanel 和多个对象。

如果您真的希望它在用户无法编辑时显示实际的 TextBlock 而不是 TextBox ,您可以使用 ContentControl 并使用 DataTrigger

切换它的 ContentTemplate 属性
<DataGrid.Resources>
<DataTemplate x:Key="TextBoxTemplate">
<TextBox Text="{Binding Path=.}" />
</DataTemplate>
</DataGrid.Resources>

...

<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ContentControl x:Name="salesControl" Content="{Binding Sales}" />
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Department}" Value="Retail">
<Setter TargetName="salesControl"
Property="ContentTemplate"
Value="{StaticResource TextBoxTemplate}" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

关于c# - 如何防止 DataGridTemplateColumn 根据某些条件进入编辑模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15551651/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com