Non credo che la creazione di un insieme di controllo per la necessità. Il problema che stai incontrando deriva dal fatto che il posto dove vedi 'il controllo' non è proprio la casella di controllo, è un proiettile. Se guardiamo allo ControlTemplate per un CheckBox possiamo vedere come ciò accade (anche se mi piace il modello di Blend meglio). Come parte di ciò, anche se l'associazione sulla proprietà IsChecked è impostata su OneWay, viene comunque aggiornata nell'IU, anche se non sta impostando il valore di binding.
Come tale, un modo molto semplice per risolvere questo problema, è modificare semplicemente il ControlTemplate per la casella di controllo in questione.
Se utilizziamo Blend per afferrare il modello di controllo, possiamo vedere il Bullet all'interno del ControlTemplate che rappresenta l'effettiva area di checkbox.
<BulletDecorator SnapsToDevicePixels="true"
Background="Transparent">
<BulletDecorator.Bullet>
<Microsoft_Windows_Themes:BulletChrome Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
IsChecked="{TemplateBinding IsChecked}"
RenderMouseOver="{TemplateBinding IsMouseOver}"
RenderPressed="{TemplateBinding IsPressed}" />
</BulletDecorator.Bullet>
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
RecognizesAccessKey="True" />
</BulletDecorator>
Qui, l'IsChecked e RenderPressed sono ciò che sono in realtà facendo il 'Il check' apparire, in modo da risolvere il problema, siamo in grado di rimuovere l'associazione dalla proprietà IsChecked sulla ComboBox e utilizzarlo per sostituire il TemplateBinding su la proprietà IsChecked del Bullet.
Ecco un piccolo esempio che dimostra l'effetto desiderato, si noti che per mantenere il Vista CheckBox guardare il PresentationFramework.Aero dll deve essere aggiunto al progetto.
<Window x:Class="Sample.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
Title="Window1"
Height="300"
Width="300">
<Window.Resources>
<SolidColorBrush x:Key="CheckBoxFillNormal"
Color="#F4F4F4" />
<SolidColorBrush x:Key="CheckBoxStroke"
Color="#8E8F8F" />
<Style x:Key="EmptyCheckBoxFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle SnapsToDevicePixels="true"
Margin="1"
Stroke="Black"
StrokeDashArray="1 2"
StrokeThickness="1" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="CheckRadioFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle SnapsToDevicePixels="true"
Margin="14,0,0,0"
Stroke="Black"
StrokeDashArray="1 2"
StrokeThickness="1" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="CheckBoxStyle1"
TargetType="{x:Type CheckBox}">
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
<Setter Property="Background"
Value="{StaticResource CheckBoxFillNormal}" />
<Setter Property="BorderBrush"
Value="{StaticResource CheckBoxStroke}" />
<Setter Property="BorderThickness"
Value="1" />
<Setter Property="FocusVisualStyle"
Value="{StaticResource EmptyCheckBoxFocusVisual}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<BulletDecorator SnapsToDevicePixels="true"
Background="Transparent">
<BulletDecorator.Bullet>
<Microsoft_Windows_Themes:BulletChrome Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
RenderMouseOver="{TemplateBinding IsMouseOver}" />
</BulletDecorator.Bullet>
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
RecognizesAccessKey="True" />
</BulletDecorator>
<ControlTemplate.Triggers>
<Trigger Property="HasContent"
Value="true">
<Setter Property="FocusVisualStyle"
Value="{StaticResource CheckRadioFocusVisual}" />
<Setter Property="Padding"
Value="4,0,0,0" />
</Trigger>
<Trigger Property="IsEnabled"
Value="false">
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<StackPanel>
<CheckBox x:Name="uiComboBox"
Content="Does not set the backing property, but responds to it.">
<CheckBox.Style>
<Style TargetType="{x:Type CheckBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<BulletDecorator SnapsToDevicePixels="true"
Background="Transparent">
<BulletDecorator.Bullet>
<Microsoft_Windows_Themes:BulletChrome Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
RenderMouseOver="{TemplateBinding IsMouseOver}"
IsChecked="{Binding MyBoolean}">
</Microsoft_Windows_Themes:BulletChrome>
</BulletDecorator.Bullet>
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
RecognizesAccessKey="True" />
</BulletDecorator>
<ControlTemplate.Triggers>
<Trigger Property="HasContent"
Value="true">
<Setter Property="FocusVisualStyle"
Value="{StaticResource CheckRadioFocusVisual}" />
<Setter Property="Padding"
Value="4,0,0,0" />
</Trigger>
<Trigger Property="IsEnabled"
Value="false">
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</CheckBox.Style>
</CheckBox>
<TextBlock Text="{Binding MyBoolean, StringFormat=Backing property:{0}}" />
<CheckBox IsChecked="{Binding MyBoolean}"
Content="Sets the backing property." />
</StackPanel>
</Grid>
</Window>
E il codice dietro, con il nostro supporto valore booleano:
public partial class Window1 : Window, INotifyPropertyChanged
{
public Window1()
{
InitializeComponent();
this.DataContext = this;
}
private bool myBoolean;
public bool MyBoolean
{
get
{
return this.myBoolean;
}
set
{
this.myBoolean = value;
this.NotifyPropertyChanged("MyBoolean");
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
#endregion
}
Grazie, questa è un'ottima risposta, cercherò di avere una lettura su ControlTemplates, c'è un modo per creare il modello in un file separato in modo da poterlo solo #utilizzare e applicarlo? I'll go. evviva ed –
La pratica preferita è applicare qualsiasi ControlTemplate con uno stile, come mostrato sopra. Quello che puoi fare è creare lo stile in un ResourceDictionary separato, quindi applicarlo al CheckBox impostando Style = "{StaticResource MyStyleName}" Se vuoi seguire questa strada, dovresti anche cercare ResourceDictionary.MergedDictionaries in modo che puoi unire le risorse in xaml anziché in C#. – rmoore
Sono costantemente stupito di quanto lavoro possa essere facile in wpf. Ho optato per disabilitare IsHitTestVisible e Focusable invece. – Goran