1

デバイスのレベルを表示する一連のコントロールのスタイルを設定しようとしています。

そのフィールドの値が特定の値の間にあるかどうかをチェックし、ハイライトを適用してエラーを示すマルチデータ トリガーを備えたスタイルを持つ Label コントロールを使用しています。

<Style x:Key="highlight-stat" TargetType="Label">
    <Style.Triggers>
        <MultiDataTrigger>
            <MultiDataTrigger.Conditions>
                <Condition Value="True">
                    <Condition.Binding>
                        <MultiBinding Converter="{StaticResource BetweenValuesConverter}">
                            <Binding/>
                            <Binding>
                                <Binding.Source>
                                    <sys:Int32>100</sys:Int32>
                                </Binding.Source>
                            </Binding>
                            <Binding>
                                <Binding.Source>
                                    <sys:Int32>200</sys:Int32>
                                </Binding.Source>
                            </Binding>
                            <Binding>
                                <Binding.Source>
                                    <sys:Boolean>True</sys:Boolean>
                                </Binding.Source>
                            </Binding>
                            <Binding>
                                <Binding.Source>
                                    <sys:Boolean>False</sys:Boolean>
                                </Binding.Source>
                            </Binding>
                        </MultiBinding>
                    </Condition.Binding>
                </Condition>
            </MultiDataTrigger.Conditions>
            <MultiDataTrigger.Setters>
                <Setter Property="Background" Value="Red"/>
                <Setter Property="Foreground" Value="White"/>
                <Setter Property="FontWeight" Value="Bold"/>
            </MultiDataTrigger.Setters>
    </Style.Triggers>
</Style>

私が取り組もうとしている問題は、通常、通常、警告、およびエラーの 2 つまたは 3 つの状態があるということです。これらの状態は、複数のフィールドに適用されます。

トリガーのセッターを、List のように個別に保存できる静的リソースに統合し、このリストを MultiDataTrigger.Setters の値として単純に使用できるようにしたいと考えています。このようにして、エラーと警告の状態をセッターのコレクションとして定義し、中央の場所から更新することができます。

いいえ:

<Style x:Key="error-state" TargetType="Control">
    <Setter Property="Foreground" Value="Red"/>
    <Setter Property="Background" Value="White"/>
    <Setter Property="FontWeight" Value="Bold"/>
</Style>
<Style x:Key="warning-state" TargetType="Control">
    <Setter Property="Background" Value="Yellow"/>
</Style>

私が抱えている問題は、DataTrigger/MultiDataTrigger の Setters プロパティに set メソッドがなく、状態を判断するためにトリガーが必要なことです。

私がやりたいことを達成する方法はありますか?

可能な解決策:

  • 範囲のリストを受け取り、正しいスタイルを適用するコントロール
  • セッターを1つのトリガーから別のトリガーにコピー/貼り付け*現在これを使用*
  • @PieterWitvoet推奨StyleSelector

編集

目的を達成するためのユーザー コントロールを作成しました。C#

public class Label : System.Windows.Controls.Label, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public Label()
    {
        var metadata = ContentProperty.GetMetadata(this);
        ContentProperty.OverrideMetadata(typeof(Label), new FrameworkPropertyMetadata(propertyChanged));

        Rules = new List<HighlightingRule>();
        PropertyChanged += (o, a) =>
        {
            System.Diagnostics.Debug.WriteLine(string.Format("#triggered - {0}", a.PropertyName));
        };
    }

    /// <summary>
    /// Gets or sets the highlighting rules applied by this control
    /// </summary>
    public List<HighlightingRule> Rules { get; set; }

    static void propertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs args)
    {
        if (o is Label)
        {
            (o as Label).reapplyRules();
        }
    }


    void reapplyRules()
    {
        Style = null;
        foreach (var rule in Rules)
        {
            if (rule.IsMatch(Content))
            {
                Style = rule.MatchStyle;
                break;
            }
        }
    }
}

以下の基本クラスを使用してルールを定義しています

/// <summary>
/// Base Class for Highlighting rules used by HighlightedLabel
/// </summary>
public abstract class HighlightingRule
{
    public Style MatchStyle { get; set; }

    public virtual bool IsMatch(object value)
    {
        return false;
    }
}

例えば:

public class UnderValueRule : HighlightingRule
{
    public double Value { get; set; }
    public bool Inclusive { get; set; }

    public override bool IsMatch(object value)
    {
        if (value is int || value is double)
        {
            double dValue = Convert.ToDouble(value);
            return dValue.CompareTo(Value) <= (Inclusive ? 0 : -1);
        }
        else if (value is decimal)
        {
            decimal dValue = Convert.ToDecimal(value);
            return dValue.CompareTo(Convert.ToDecimal(Value)) <= (Inclusive ? 0 : -1);
        }
        return false;
    }
}

XAML の場合:

<rules:UnderValueRule Value="31" Inclusive="False" MatchStyle="{StaticResource error-state}"/>
4

0 に答える 0