36

データ コンテキスト内のプロパティの値に応じて複数のスタイルが適用されるカスタム コントロール (ボタン) を作成しようとしています。

私が考えていたのは、次のようなものを使用していることです。

<Button Style="{Binding Path=ButtonStyleProperty, Converter={StaticResource styleConverter}}" Text="{Binding Path=TextProp}" />

ConvertToそしてコードで...メソッドで以下のコードに似た処理を行う IValueConverter を実装します。

switch(value as ValueEnums)
{
    case ValueEnums.Enum1:
        FindResource("Enum1ButtonStyle") as Style;
    break;

    ... and so on.
} 

ただし、スタイルオブジェクトを引き出す方法については完全にはわかりません。これが可能であるとしても...

私がその間に行っているのは、イベントを処理し、ボタンにバインドされているオブジェクトDataContextChangedのイベントにハンドラーをアタッチしPropertyChanged、そこで switch ステートメントを実行することです。

完璧ではありませんが、より良い解決策が見つかるまで、それを使用する必要があるようです。

4

4 に答える 4

40

スタイルの要素だけではなく、スタイル全体を置き換えたい場合は、おそらくそれらのスタイルをリソースに保存することになります。次の行に沿って何かを実行できるはずです。

<Button>
    <Button.Style>
        <MultiBinding Converter="{StaticResource StyleConverter}">
            <MultiBinding.Bindings>
                <Binding RelativeSource="{RelativeSource Self}"/>
                <Binding Path="MyStyleString"/>
            </MultiBinding.Bindings>
        </MultiBinding>
    </Button.Style>
</Button>

MultiBinding を使用し、Self を最初のバインディングとして使用することで、コンバーターでリソースを検索できます。コンバーターは (IValueConverter ではなく) IMultiValueConverter を実装する必要があり、次のようになります。

class StyleConverter : IMultiValueConverter 
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        FrameworkElement targetElement = values[0] as FrameworkElement; 
        string styleName = values[1] as string;

        if (styleName == null)
            return null;

        Style newStyle = (Style)targetElement.TryFindResource(styleName);

        if (newStyle == null)
            newStyle = (Style)targetElement.TryFindResource("MyDefaultStyleName");

        return newStyle;
    }

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

それは私が頻繁に行うことではありませんが、それは記憶から機能するはずです:)

于 2009-01-04T08:45:18.570 に答える
18

DataTriggerクラスを使用する必要があるようです。ボタンのコンテンツに基づいて、さまざまなスタイルをボタンに適用できます。

たとえば、次のスタイルは、データ コンテキスト オブジェクトのプロパティの値に基づいて、ボタンの背景プロパティを赤に変更します。

<Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
    <Style.Triggers>
        <DataTrigger Binding="{Binding Path="Some property"}" 
                     Value="some property value">
            <Setter Property="Background" Value="Red"/>
        </DataTrigger>
    </Style.Triggers>
</Style>
于 2009-01-04T07:16:50.293 に答える
8

多値コンバーターを使用できない私たちのために (SL4 と WP7 を見ています:)、Steven の回答のおかげで、通常の値コンバーターを使用する方法を見つけました。

唯一の前提は、設定されているスタイルのプロパティ内にスタイル値が含まれていることです。

したがって、MVVM パターンを使用している場合、スタイル値 (TextSmall、TextMedium、TextLarge など) はビュー モデルの一部であると見なされ、スタイルの名前を定義するコンバーター パラメーターを渡すだけで済みます。

たとえば、ビュー モデルに次のプロパティがあるとします。

public string ProjectNameStyle
{
    get { return string.Format("ProjectNameStyle{0}", _displaySize.ToString()); }
}

アプリケーション スタイル:

<Application.Resources>
    <Style x:Key="ProjectNameStyleSmall" TargetType="TextBlock">
        <Setter Property="FontSize" Value="40" />
    </Style>
    <Style x:Key="ProjectNameStyleMedium" TargetType="TextBlock">
        <Setter Property="FontSize" Value="64" />
    </Style>
    <Style x:Key="ProjectNameStyleLarge" TargetType="TextBlock">
        <Setter Property="FontSize" Value="90" />
    </Style>

XAML ビュー:

   <TextBlock 
        Text="{Binding Name}"
        Style="{Binding ., Mode=OneWay, Converter={cv:StyleConverter}, ConverterParameter=ProjectNameStyle}">

IValueConverter を実装する StyleConverter クラスの場合:

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    if (targetType != typeof(Style))
    {
        throw new InvalidOperationException("The target must be a Style");
    }

    var styleProperty = parameter as string;
    if (value == null || styleProperty == null)
    {
        return null;
    }

    string styleValue = value.GetType()
        .GetProperty(styleProperty)
        .GetValue(value, null)
        .ToString();
    if (styleValue == null)
    {
        return null;
    }

    Style newStyle = (Style)Application.Current.TryFindResource(styleValue);
    return newStyle;
}

コンバーターは IValueConverter と同様に MarkupExtension から派生しているため、これは WPF コードであることに注意してください。

それが誰かを助けることを願っています、そして再びスティーブンに感謝します!

于 2011-05-27T08:04:03.090 に答える