【问题标题】:How do I make a ControlTemplate (for a checkbox) readonly in WPF/MVVM?如何在 WPF/MVVM 中将 ControlTemplate(用于复选框)设为只读?
【发布时间】:2011-10-06 12:06:04
【问题描述】:

我有一个 WPF 数据网格,我在其中为复选框创建了一个 ControlTemplate 来表示 bool? 类型。 我希望复选框/控件模板对用户只读,但能够更改值

这是模板:

<ControlTemplate x:Key="checkboxTemplate" TargetType="CheckBox">
    <Grid Background="{TemplateBinding Background}" Height="{TemplateBinding Height}">
        <Rectangle x:Name="r" Height="10" Width="40" HorizontalAlignment="Center" VerticalAlignment="Center" RadiusX="4" RadiusY="4"></Rectangle>
    </Grid>
    <ControlTemplate.Triggers>
        <Trigger Property="CheckBox.IsChecked" Value="True">
            <Setter Property="Fill" Value="#FF66D660" TargetName="r"></Setter>
        </Trigger>
        <Trigger Property="CheckBox.IsChecked" Value="False">
            <Setter Property="Fill" Value="#FFD50005" TargetName="r"></Setter>
        </Trigger>
        <Trigger Property="CheckBox.IsChecked" Value="{x:Null}">
            <Setter Property="Fill" Value="SlateGray" TargetName="r"></Setter>
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

这是数据网格中的实现:

<DataGridTemplateColumn SortMemberPath="IsReady" Header="Ready" CanUserSort="True" IsReadOnly="True">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <CheckBox IsChecked="{Binding IsReady, Mode=OneWay}" HorizontalAlignment="Center" Template="{StaticResource checkboxTemplate}" />
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

【问题讨论】:

  • 您希望您的 CheckBox 为 ReadOnly,但您希望用户能够更改它的 Checked 值?那你为什么要它 ReadOnly 呢?只是为了风格?
  • @Rachel:对用户只读,可从代码编辑。
  • @jberger 我以为您是 OP,所以根据您的评论发布了答案。现在意识到你不是,所以答案可能不适用于他的情况。

标签: wpf mvvm controltemplate


【解决方案1】:

您可以在复选框上设置 IsHitTestVisible="false" 或 IsEnabled="false"。

【讨论】:

  • 完美简单的解决方案
  • 不是一个完美的解决方案。即使 IsHitTestVisible=False 将焦点移到复选框并按空格键也会切换它
【解决方案2】:

使其成为只读的最简单方法是将其移动到具有几乎透明背景的某些控件后面。

<DataTemplate>
  <Border Opacity="0.01" Background="White">
   <CheckBox IsChecked="{Binding IsReady, Mode=OneWay}" HorizontalAlignment="Center" Template="{StaticResource checkboxTemplate}" />
  </Border>
</DataTemplate>

【讨论】:

  • 是的,同意,IsEnabled="false" 容易得多:)
【解决方案3】:

如果您从代码中编辑 Checked 值,则应该编辑绑定源 (IsReady),而不是 CheckBox.Checked 值。设置 MyCheckBox.Checked 将覆盖绑定,并且不会将更改保存到您的 IsReady 属性。

最好从您的 ViewModel 更改 IsReady 属性,但如果您必须从 View 后面执行此操作,我通常会将 CheckBox 的 DataContext 转换为我的数据对象,并从那里设置绑定属性

类似这样的:

((MyDataObject)MyCheckBox.DataContext).IsReady = false;

至于让 CheckBox 对用户只读,请将其 IsEnabled 属性设置为 false

<CheckBox x:Name="MyCheckBox" IsEnabled="False" IsChecked="{Binding IsReady}" />

【讨论】:

  • 我认为 IsReady 应该只从 ViewModel 更新(而不是在 View 代码转换为 ViewModel 类型)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-29
  • 1970-01-01
  • 2011-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多