【问题标题】:WPF Enable Disable Border based on MultiDataTrigger not workingWPF基于MultiDataTrigger启用禁用边框不起作用
【发布时间】:2014-11-07 04:34:27
【问题描述】:

我在 WPF 中有一个边框,我试图根据视图模型中的两个属性启用或禁用它:ConnectedVisibility 和 OperatingMode。当 connectedvisibility 可见性未设置为“可见”时,此数据触发器会禁用边框。但它不适用于操作模式。对于非 0 的操作模式,应禁用边框但仍保持启用状态。看起来 OperatingMode 改变它的值根本没有影响。除非程序第一次启动,否则即使我在转换器中放置的断点也不会被命中。绑定看起来不错,因为这些绑定的调试输出中没有显示任何问题。任何帮助表示赞赏。

风格是

<Style x:Key="EnableOnConnectBorderCorrected" TargetType="{x:Type Border}">
    <!--<Setter Property="BorderBrush" Value="#FFDADADA"/>-->
    <Setter Property="BorderBrush" Value="Red"/>
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="CornerRadius" Value="2"/>
    <Style.Triggers>
        <MultiDataTrigger>
            <MultiDataTrigger.Conditions>
                <Condition Binding="{Binding ConnectedVisibility}" Value="Visible"/>
                <Condition Binding="{Binding OperatingMode}" Value="0"/>
            </MultiDataTrigger.Conditions>
            <Setter Property="IsEnabled" Value="True"/>
        </MultiDataTrigger>
        <DataTrigger Binding="{Binding OperatingMode, Converter={x:Static VM:IsEqualOrGreaterThanSHORTConverter.Instance}, ConverterParameter=1,Mode=TwoWay}" Value="True">
            <Setter Property="IsEnabled" Value="False"/>
        </DataTrigger>
        <DataTrigger Binding="{Binding ConnectedVisibility}" Value="Collapsed">
            <Setter Property="IsEnabled" Value="False"/>
        </DataTrigger>
    </Style.Triggers>
</Style>

样式中使用的转换器是->

public class IsEqualOrGreaterThanSHORTConverter : IValueConverter
{
    public static readonly IValueConverter Instance = new IsEqualOrGreaterThanSHORTConverter();

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        short iValue = (short)value;
        short compareToValue = System.Convert.ToInt16(parameter);

        return iValue >= compareToValue;
    }

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

应用此样式的 XAML 是

<Border Name="RebootDash" Grid.Row="2" Grid.Column="1" Style="{StaticResource EnableOnConnectBorderCorrected}" BorderBrush="#FFDADADA" BorderThickness="1" CornerRadius="2" Width="Auto" Margin="0,1,1,0">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Border Grid.Row="2" Background="Wheat"/>
        <telerik:RadButton Command="{Binding ResetUnitCommand, Source={StaticResource UnitCommandProvider}}" Style="{StaticResource DashBoardImageButton}">
            <Image Grid.Row="0" Source="/Images/UnitManagementImages/IMG_THOR_UNITResetUnit128.png"
                   ToolTip="{x:Static properties:Resources.Unit_Command_ResetUnit}" 
                   Width="40" Height="40"
                   Margin="0,5,0,5"
                   HorizontalAlignment="Center"/>
        </telerik:RadButton>
        <TextBlock Grid.Row="2" Text="{x:Static properties:Resources.Unit_Command_ResetUnit}" HorizontalAlignment="Center" Margin="5,5,5,5"/>
    </Grid>
</Border>

它所绑定的属性是

public Visibility ConnectedVisibility
{
    get { return connectedVisibility; }
    set
    {
        if (connectedVisibility == value) return;
        connectedVisibility = value;
        RaisePropertyChanged("ConnectedVisibility");
    }
}

public short OperatingMode
{
    get { return UnitOperatingModeVM.OperatingMode; }
    set
    {
        UnitOperatingModeVM.OperatingMode = value;
    }
}

【问题讨论】:

    标签: c# wpf xaml datatrigger multidatatrigger


    【解决方案1】:

    由于您只有一个条件可以启用相同功能,因此默认情况下将 IsEnabled 设置为 False 应该可以解决问题

    <Style x:Key="EnableOnConnectBorderCorrected" TargetType="{x:Type Border}">
        <!--<Setter Property="BorderBrush" Value="#FFDADADA"/>-->
        <Setter Property="BorderBrush" Value="Red"/>
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="CornerRadius" Value="2"/>
        <Setter Property="IsEnabled" Value="False"/>
        <Style.Triggers>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding ConnectedVisibility}" Value="Visible"/>
                    <Condition Binding="{Binding OperatingMode}" Value="0"/>
                </MultiDataTrigger.Conditions>
                <Setter Property="IsEnabled" Value="True"/>
            </MultiDataTrigger>
        </Style.Triggers>
    </Style>
    

    我在样式中添加了&lt;Setter Property="IsEnabled" Value="False"/&gt;,默认情况下会禁用控件,并且我已经删除了其他冗余条件

    所以当 MultiDataTrigger 中的两个条件都满足时,它会启用相同的结果,否则它会保持禁用状态

    以上示例假设 MultiDataTrigger ConnectedVisibilityOperatingMode 中的两个属性都在通知更改。


    您可能还需要为 OperatingMode 添加通知,以便 MultiDataTrigger 触发触发器

    public short OperatingMode
    {
        get { return UnitOperatingModeVM.OperatingMode; }
        set
        {
            UnitOperatingModeVM.OperatingMode = value;
            RaisePropertyChanged("OperatingMode");
        }
    }
    

    【讨论】:

    • 感谢您的回答。现在,即使同时满足两个条件,样式也始终保持禁用状态。可能是因为 setter 总是触发而 MultiDataTrigger 根本不触发。
    • 似乎您还需要在 OperatingMode 属性设置器中添加 RaisePropertyChanged("OperatingMode"); 。如前所述,MultiDataTrigger 只会在属性通知更改并具有正确值时触发。所以将 RaisePropertyChanged 添加到 OperatingMode 应该没问题。
    【解决方案2】:

    你的OperatingMode属性集实现是否调用了RaisePropertyChanged("OperatingMode");

    private short operatingMode;
    public short OperatingMode
    {
        get
        {
            return operatingMode;
        }
        set
        {
            if (operatingMode != value)
            {
                operatingMode = value;
                this.RaisePropertyChanged("OperatingMode");
            }
    
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-04
      • 2014-07-05
      • 2013-07-03
      • 2021-10-21
      相关资源
      最近更新 更多