根据对象类型取消绑定

时间:2016-08-26 13:14:27

标签: wpf data-binding

在我的WPF应用程序中,我有一个绑定到Text-property长度的标签:

var longToDate=function(millisec){
    var length=millisec.length-7;
    var date=millisec.substring(6,length);
    return (new Date(millisec.substring(6,length)).toUTCString());
} 

Editor-object可以是文本框或复选框。文本框确实具有Text属性,而复选框没有 当Label绑定到“checkbox-editor”时,它会在Visual Studio中生成警告:

  

BindingExpression路径错误:'object'上找不到'Text'属性...

这是预期的,我想知道是否有任何方法告诉绑定引擎不要尝试绑定此值,除非Editor-object是文本框?

1 个答案:

答案 0 :(得分:2)

您的viewmodel的Editor属性是否为控件?我希望不是,但无论如何。

您可以编写一个返回值类型的valueconverter,然后通过Style中的一系列触发器设置Label的内容。如果编辑类型为{x:Type TextBox},请将其设置为您上面的绑定。如果它是{x:Type CheckBox},请将其设为`{Binding Editor.IsChecked}'。

XAML

<Label>
    <Label.Style>
        <Style TargetType="Label" BasedOn="{StaticResource {x:Type Label}}">
            <Style.Triggers>
                <DataTrigger 
                    Binding="{Binding ElementName=Editor, Converter={local:GetTypeConverter}}"
                    Value="{x:Type TextBox}"
                    >
                    <Setter 
                        Property="Content" 
                        Value="{Binding Text.Length, ElementName=Editor}" 
                        />
                </DataTrigger>
                <DataTrigger 
                    Binding="{Binding ElementName=Editor, Converter={local:GetTypeConverter}}"
                    Value="{x:Type CheckBox}"
                    >
                    <Setter 
                        Property="Content" 
                        Value="{Binding IsChecked, ElementName=Editor}" 
                        />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Label.Style>
</Label>

C#

public class GetTypeConverter : MarkupExtension, IValueConverter
{
    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return this;
    }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value?.GetType();
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

或者,您的viewmodel可以具有readonly属性,该属性返回该标签中应该包含的内容,因为viewmodel具有Editor并且知道它是什么。暂时将其称为EditorLabelValue。据推测,Editor绑定到string属性或bool属性,具体取决于它是哪个编辑器。因此,这两个setter都会为PropertyChanged引发"EditorLabelValue",这将返回适当的值。

我试图在纯XAML中执行此操作,方法是Editor Content ContentControl然后使用DataTemplates,但我无法找到一种方法来实现没有获得重新定位Editor的例外工作。