.net 绑定自默认值的三状态复选框

.net 绑定自默认值的三状态复选框,.net,wpf,xaml,.net,Wpf,Xaml,当设置IsChecked绑定时,如何将三态复选框默认为null?FallbackValue=“{x:Null}”似乎不起作用?我试图使复选框默认为null而不是false <CheckBox IsThreeState="True"> <CheckBox.IsChecked> <Binding RelativeSource="{RelativeSource Self}" Path="IsChecked"

当设置IsChecked绑定时,如何将三态复选框默认为null?FallbackValue=“{x:Null}”似乎不起作用?我试图使复选框默认为null而不是false

<CheckBox IsThreeState="True">
    <CheckBox.IsChecked>
        <Binding RelativeSource="{RelativeSource Self}"
                 Path="IsChecked"
                 FallbackValue="{x:Null}"
                 UpdateSourceTrigger="Explicit">
            <Binding.ValidationRules>
                <Validators:StandardValidators />
            </Binding.ValidationRules>
        </Binding>
    </CheckBox.IsChecked>
</CheckBox>

更新1: 要显式触发验证,我使用:

    private void SaveChanges()
    {
         if (!this.ValidateForm(this.GridContainingCheckboxes))
         {
              return;
         {

         var myObject = new CustomObject();
         myObject.InspectedElement = myCheckbox.IsChecked;

         // Save Stuff Here
    }

    private bool ValidateForm(DependencyObject obj)
    {
        var result = true;

        foreach (var checkBox in this.ChildrenOfType<CheckBox>())
        {
            var bindingExpression = BindingOperations.GetBindingExpression(checkBox, ToggleButton.IsCheckedProperty);

            if (bindingExpression != null)
            {
                bindingExpression.UpdateSource();
            }
        }

        if (!this.IsValid(obj))
        {
            result = false;
        }

        return result;
    }

    private bool IsValid(DependencyObject obj)
    {
        return !Validation.GetHasError(obj) && LogicalTreeHelper.GetChildren(obj).OfType<DependencyObject>().All(child => this.IsValid(child));
    }
private void SaveChanges()
{
如果(!this.ValidateForm(this.gridContaining复选框))
{
返回;
{
var myObject=new CustomObject();
myObject.InspectedElement=myCheckbox.IsChecked;
//在这里保存东西
}
私有布尔ValidateForm(DependencyObject对象对象)
{
var结果=真;
foreach(此.ChildrenOfType()中的var复选框)
{
var bindingExpression=BindingOperations.GetBindingExpression(复选框,ToggleButton.IsCheckedProperty);
if(bindingExpression!=null)
{
bindingExpression.UpdateSource();
}
}
如果(!this.IsValid(obj))
{
结果=假;
}
返回结果;
}
私有布尔值有效(DependencyObject对象)
{
return!Validation.GetHasError(obj)和&logicaltreeheloper.GetChildren(obj).OfType().All(child=>this.IsValid(child));
}
更新2:

public class StandardValidators : ValidationRule
{
    /// <summary>
    /// Initializes a new instance of the <see cref="StandardValidators"/> class.
    /// </summary>
    public StandardValidators()
    {
        this.AllowNull = false;
    }

    /// <summary>
    /// Gets or sets ErrorMessage.
    /// </summary>
    public string ErrorMessage { get; set; }

    /// <summary>
    /// Gets or sets a value indicating whether AllowNull.
    /// </summary>
    public bool AllowNull { get; set; }

    /// <summary>
    /// Gets or sets a value indicating whether IsBoolean.
    /// </summary>
    public bool IsBoolean { get; set; }

    /// <summary>
    /// The main validator.
    /// </summary>
    /// <param name="value">
    /// The value.
    /// </param>
    /// <param name="cultureInfo">
    /// The culture info.
    /// </param>
    /// <returns>
    /// The validation result.
    /// </returns>
    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        var result = new ValidationResult(true, null);

        if (!this.AllowNull)
        {
            if (this.IsBoolean && (value as bool?) == null)
            {
                this.ErrorMessage = "Cannot Be Null";
                return new ValidationResult(false, this.ErrorMessage);
            }
        }

        return result;
    }
}
公共类StandardValidators:ValidationRule
{
/// 
///初始化类的新实例。
/// 
公共标准验证器()
{
this.AllowNull=false;
}
/// 
///获取或设置错误消息。
/// 
公共字符串错误消息{get;set;}
/// 
///获取或设置一个值,该值指示是否AllowNull。
/// 
公共布尔AllowNull{get;set;}
/// 
///获取或设置一个值,该值指示是否为布尔值。
/// 
公共布尔值是布尔值{get;set;}
/// 
///主验证器。
/// 
/// 
///价值。
/// 
/// 
///文化信息。
/// 
/// 
///验证结果。
/// 
公共覆盖验证结果验证(对象值,CultureInfo CultureInfo)
{
var结果=新的ValidationResult(真,空);
如果(!this.AllowNull)
{
if(this.IsBoolean&&(值为bool?==null)
{
this.ErrorMessage=“不能为空”;
返回新的ValidationResult(false,this.ErrorMessage);
}
}
返回结果;
}
}

之所以
回退值
不起作用,是因为
复选框
已被选中
具有有效值(false),因此它将使用该值而不是
回退值

根据您使用
OverrideMetadata
附加的示例,在您的解决方案中似乎工作得很好,下面是我使用的代码

public MainWindow()
{
    CheckBox.IsCheckedProperty.OverrideMetadata(typeof(CheckBox), new FrameworkPropertyMetadata((bool?)null));
    InitializeComponent();

    // if you want to show validation errors on load.
    Loaded += (s, e) => this.ValidateForm(this.MainGrid);
}

您可以在
EventTrigger
()中设置的默认值:


System.Windows.Interactivity.dll程序集您可以在Microsoft Expression Blend 3 SDK中找到(.

因此任何内容都不会绑定到复选框您只想将其显示为默认值为null?如果此复选框未绑定到任何内容,该复选框会做什么?这似乎不会让UpdateSource()激发并触发验证规则。您想做什么?如果复选框未绑定到任何内容,您要验证什么。请确认用户已与复选框交互,并且分配的值为true或false,但不为null。默认情况下,它需要为null,因为对于检查,用户必须进行选择。以下是指向测试项目。验证(红色突出显示是我想要的,也是最早的验证。)您可以覆盖IsChecked的元数据以显示为null,在上面添加了示例,以防止用户编辑复选框的值。@BitOriented check my answer:)
<CheckBox x:Name="chb" IsThreeState="True">
...
    <CheckBox.Triggers>
        <EventTrigger RoutedEvent="CheckBox.Loaded">
            <BeginStoryboard>
                <Storyboard>
                    <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetName="chb"
                            Storyboard.TargetProperty="IsChecked">
                        <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Null}" />
                    </ObjectAnimationUsingKeyFrames>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </CheckBox.Triggers>
</CheckBox>
public class SetterAction : TriggerAction<DependencyObject>
{
    public SetterAction()
    {
        Setters = new List<Setter>();
    }

    public List<Setter> Setters { get; set; }

    protected override void Invoke(object parameter)
    {
        foreach (var item in Setters)
        {
            AssociatedObject.SetValue(item.Property, item.Value);
        }
    }
}
<CheckBox x:Name="InspectOverallUnitToggleButton" IsThreeState="True">
    <CheckBox.IsChecked>
        <Binding RelativeSource="{RelativeSource Self}"
                 Path="IsChecked"
                 FallbackValue="{x:Null}"
                 UpdateSourceTrigger="Explicit">
            <Binding.ValidationRules>
                <Validators:StandardValidators IsBoolean="True"/>
            </Binding.ValidationRules>
        </Binding>
    </CheckBox.IsChecked>              
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Loaded">
            <i:EventTrigger.Actions>
                <local:SetterAction>
                    <local:SetterAction.Setters>
                        <Setter Property="CheckBox.IsChecked" Value="{x:Null}" />
                    </local:SetterAction.Setters>
                </local:SetterAction>
            </i:EventTrigger.Actions>
        </i:EventTrigger>                  
    </i:Interaction.Triggers>
</CheckBox>
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"