デバイスのレベルを表示する一連のコントロールのスタイルを設定しようとしています。
そのフィールドの値が特定の値の間にあるかどうかをチェックし、ハイライトを適用してエラーを示すマルチデータ トリガーを備えたスタイルを持つ 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}"/>