Как сделать ControlTemplate (для флажка) доступным только для чтения в WPF/MVVM?

У меня есть сетка данных 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>

Вот реализация в datagrid:

<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>

person NBPC77    schedule 06.10.2011    source источник
comment
Вы хотите, чтобы ваш CheckBox был доступен только для чтения, но вы хотите, чтобы пользователь мог изменить его значение Checked? Почему вы хотите, чтобы это было только для чтения? Только для стиля?   -  person Rachel    schedule 06.10.2011
comment
@Rachel: только для чтения для пользователя, редактируемый из кода.   -  person Jake Berger    schedule 07.10.2011
comment
@jberger Я думал, что ты ОП, поэтому отправил ответ на основе твоего комментария. Поймите теперь, что это не так, поэтому ответ может не относиться к его ситуации.   -  person Rachel    schedule 07.10.2011


Ответы (3)


Вы можете установить флажок IsHitTestVisible="false" или IsEnabled="false".

person Joe Mancuso    schedule 06.10.2011
comment
Идеальное простое решение - person Manuel Amstutz; 26.06.2015
comment
Не идеальное решение. Перемещение фокуса на флажок и нажатие клавиши пробела переключает его, даже если IsHitTestVisible=False - person Nir Kornfeld; 20.07.2016

Самый простой способ сделать это только для чтения, чтобы переместить его за какой-то элемент управления с почти прозрачным фоном.

<DataTemplate>
  <Border Opacity="0.01" Background="White">
   <CheckBox IsChecked="{Binding IsReady, Mode=OneWay}" HorizontalAlignment="Center" Template="{StaticResource checkboxTemplate}" />
  </Border>
</DataTemplate>
person Sergei B.    schedule 06.10.2011
comment
Ага, согласен, IsEnabled=false гораздо проще :) - person Sergei B.; 06.10.2011

Если вы редактируете значение Checked из кода, вы должны редактировать источник привязки (IsReady), а не значение CheckBox.Checked. Установка MyCheckBox.Checked перезапишет привязку и не сохранит изменения в вашем свойстве IsReady.

Предпочтительно изменить свойство IsReady из вашей ViewModel, но если вы должны сделать это из-за представления, я обычно привожу DataContext CheckBox к моему объекту данных и устанавливаю связанное свойство оттуда

Что-то вроде этого:

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

Что касается того, чтобы сделать CheckBox доступным только для чтения для пользователя, установите для свойства IsEnabled значение false.

<CheckBox x:Name="MyCheckBox" IsEnabled="False" IsChecked="{Binding IsReady}" />
person Rachel    schedule 07.10.2011
comment
Я думаю, что IsReady следует обновлять только из ViewModel (а не в коде View, приведенном к типу ViewModel). - person Jake Berger; 07.10.2011