手动评估条件

时间:2011-09-13 08:24:18

标签: c# wpf c#-4.0

当所有条件都为真时,我想将控件的“可见性”属性设置为指定值。如下例所示:

    <TextBlock Text="TEST">
        <e:Interaction.Behaviors>
            <bhv:VisibilityBehaviour VisibilityIfTrue="Visible" VisibilityIfFalse="Collapsed">
                <Condition Binding="{Binding BOOL1}" Value="true"/>
                <Condition Binding="{Binding BOOL2}" Value="true"/>
                <Condition Binding="{Binding BOOL3}" Value="true"/>
            </bhv:VisibilityBehaviour>
        </e:Interaction.Behaviors>
    </TextBlock>

我如何手动评估这些条件?我知道如何获得价值,但如果价值发生变化,我就不会收到通知。

我知道我可以使用反射获得绑定目标的值。然后我可以从条件中比较这两个值。

使用Attribute [ContentProperty(“Conditions”)],VisibilityBehavior标记之间的条件将添加到列表中。

VisibilityBehavior.cs

[ContentProperty("Conditions")]
public class VisibilityBehaviour : Behavior<FrameworkElement>
{
    public static readonly DependencyProperty VisibilityProperty;
    public Visibility Visibility
    {
        get { return (Visibility)GetValue(VisibilityProperty); }
        set { SetValue(VisibilityProperty, value); }
    }

    public Visibility VisibilityIfTrue { get; set; }
    public Visibility VisibilityIfFalse { get; set; }
    public List<Condition> Conditions { get; set; }

    static VisibilityBehaviour()
    {
        VisibilityProperty = DependencyProperty.Register("Visibility", typeof(Visibility), typeof(VisibilityBehaviour), new UIPropertyMetadata(Visibility.Visible));
    }
    public VisibilityBehaviour()
    {
        Conditions = new List<Condition>();
    }

    protected override void OnAttached()
    {
        base.OnAttached();

        FrameworkElement obj = AssociatedObject as FrameworkElement;
        if (obj == null)
            return;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();

        FrameworkElement obj = AssociatedObject as FrameworkElement;
        if (obj == null)
            return;
    }
}

如果绑定的值发生更改,我如何收到通知,例如: BOOL1为false,然后变为true。

更新:现在使用转换器

MultiValueConverter,如果所有BOOL都为真,那么它返回Visibility.Visible,否则.Collapsed

<MultiBinding Converter="{StaticResource VisibilityConverter}" ConverterParameter="true">
    <Binding Path="BOOL1"/>
    <Binding Path="BOOL2"/>
    <Binding Path="BOOL3"/>
</MultiBinding>

ValueConverter,这里没有通知条件Binding值是否改变,但在这里我可以添加整个条件

<Binding Converter="{StaticResource VisibilityConverter}">
    <Binding.ConverterParameter>
        <ConditionCollection >
            <Condition Binding="{Binding BOOL1}" Value="true"/>
            <Condition Binding="{Binding BOOL2}" Value="true"/>
            <Condition Binding="{Binding BOOL3}" Value="true"/>
        </ConditionCollection>
    </Binding.ConverterParameter>
</Binding>

我需要在这两个转换器之间进行混合,因为

  • 我想在xaml中添加条件(比如在ValueConverter中)
  • 如果Binding的值发生变化,则需要更新

任何想法?

3 个答案:

答案 0 :(得分:0)

希望我理解你的问题:

您可以将IMultiValueConverter与MultiBinding结合使用,将控件属性绑定到多个模型的属性,并在转换器内部评估结果。

查看示例。

答案 1 :(得分:0)

您不会收到通知,因为Binding对象没有变化。但是,绑定源和目标属性的值确实如此,因此您可能希望扩展Condition类(如果它是您自己的)以在绑定的TargetUpdated或SourceUpdate事件上注册并进一步传播该事件。

http://msdn.microsoft.com/de-de/library/system.windows.data.binding.aspx

同时阅读这些事件,因为有些条件需要确保(在绑定上设置一些bool)才能触发事件。

希望有所帮助。

另外,正如另一张已经提到过的海报,你可以用MultiBindings来解决你的问题,放弃你的基于行为的概念。

答案 2 :(得分:0)

您使用MultiDataTrigger处于WPF使用样式触发器中。
http://msdn.microsoft.com/en-us/library/system.windows.multidatatrigger.aspx

<Style TargetType="TextBlock">
  <Setter Property="Visibility" Value="Collapsed" />
  <Style.Triggers>
    <MultiDataTrigger>
      <MultiDataTrigger.Conditions>
        <Condition Binding="{Binding Binding1}" Value="Condition1" />
        <Condition Binding="{Binding Binding2}" Value="Condition2" />
      </MultiDataTrigger.Conditions>
      <Setter Property="Visibility" Value="Visible" />
    </MultiDataTrigger>
  </Style.Triggers>
</Style>