6

以下のように、Silverlightで動的グラデーションを使用できるようにしたいと思います。

<RadialGradientBrush GradientOrigin="0.20,0.5" Center="0.25,0.50" 
                     RadiusX="0.75" RadiusY="0.5">
  <GradientStop Color="{Binding Path=GradientStart}" Offset="0" />
  <GradientStop Color="{Binding Path=GradientEnd}" Offset="1" />
</RadialGradientBrush>

タイプ「Color」を返す2つのプロパティにバインドしていますが、常に次のメッセージが表示されます。

AG_E_PARSER_BAD_PROPERTY_VALUE

GradientStopコレクションにバインドしようとすると、これにも同じ問題があります。この問題の解決策は次のとおりです。

  1. グラデーションの開始と終了を実行時に変更できるようにします
  2. Silverlight 3.0で動作し、WPFソリューションではありません

この動作を回避する、またはとにかくこれを複製するための回避策がある場合は、LinearGradientsで機能するソリューションがあります。これは、何かの「Fill」プロパティをこれにバインドできるためです。ただし、この状況では機能しません。私が使用する可能性のある他のグラデーションタイプであり、このソリューション/代替案が適用される将来的に他の人が使用する可能性があります。

4

4 に答える 4

14

問題は、GradientStopがFrameworkElementから派生していないため、データにバインドできないことです。残念ながら、それはあなたがコードからそれを設定しなければならないことを意味します。

于 2009-10-03T20:13:41.403 に答える
5

これを実際に実現するには、2つの選択肢があります。

表示項目のBrushプロパティをデータのBrushプロパティにバインドします

データソースに、各アイテムに使用するブラシを公開するプロパティを持たせ、ブラシを使用する表示アイテムのプロパティ、たとえばプロパティをバインドしFillます。これは、開始値と停止値のペアに対して持つ個別の値のセットが小さい場合に機能します。ペアごとに各ブラシのインスタンスを作成すると、データアイテムが正しいブラシを公開します。

値コンバーターを使用して、表示項目のブラシプロパティをバインドします

StartとStopの値がより変数である場合は、表示されたアイテムごとにブラシタイプの新しいインスタンスが必要になります。この場合、値コンバーターを使用して表示アイテムのブラシプロパティをバインドします。例:-

 <Rectangle Fill="{Binding Converter={StaticResource MyBrushBuilder} }" ... >

コンバーターの構築の完全な説明については、この回答を参照してください。

この場合、convertメソッドの実装は次のようになりますが:-

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
  YourItemsType item = (YourItemsType)value;

  var start = new GradientStop();
  start.Offset = 0;
  start.Color = item.GradientStart;

  var stop = new GradientStop();
  stop.Offset = 1;
  stop.Color = item.GradientStop;

  var result = new RadialGradientBrush();
  result.GradientOrigin = new Point(0.20, 0.5);
  result.Center = new Point(0.25, 0.5);
  result.RadiusX = 0.75;
  result.RadiusY = 0.5;
  result.GradientStops = new GradientStopCollection();
  result.GradientStops.Add(start);
  result.GradientStops.Add(stop);

  return result;
}

警告

データバインディングが発生するたびに、アイテムごとに1つずつブラシが作成されます。これは費用がかかり、望ましくない場合があります。したがって、このバインディングコンバータのアプローチが必要であると思われる場合は、ブラシの静的ディクショナリを使用することをお勧めします。この辞書の鍵は、2色のハッシュです。必要な場合にのみ新しいブラシを作成し、可能な場合は以前に作成したブラシを再利用します。

于 2009-10-04T13:50:28.530 に答える
0

DataContextグラデーションブラシが定義されている場所として使用されているタイプを確認しましたか?Sourceバインディングでを指定していないため、DataContextデフォルトでを使用します。

于 2009-10-03T15:02:34.613 に答える
0

かなり古い投稿ですが、(今は)可能なので、これが私の解決策です。私のXAMLコード:

<Ellipse.Resources>
    <local:ColorConverter x:Key="ColorConverter"/>
</Ellipse.Resources>
<Ellipse.Fill>
    <RadialGradientBrush>
        <GradientStop Color="{Binding MenuColor2, Source={x:Static p:Settings.Default}, Converter={StaticResource ColorConverter}}" Offset="1" />
        <GradientStop Color="{Binding MenuColor1, Source={x:Static p:Settings.Default}, Converter={StaticResource ColorConverter}}" Offset="0.85" />
    </RadialGradientBrush>
</Ellipse.Fill>

そして、これが私のC#コードです。

[ValueConversion(typeof(System.Drawing.Color), typeof(System.Windows.Media.Color))]
public class ColorConverter : IValueConverter
{

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value is System.Drawing.Color)
        {
            var clr = (System.Drawing.Color)value;
            return System.Windows.Media.Color.FromArgb(clr.A, clr.R, clr.G, clr.B);
        }
        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value is Color)
        {
            var clr = (Color)value;
            return System.Drawing.Color.FromArgb(clr.A, clr.R, clr.G, clr.B);
        }
        return value;
    }
}
于 2015-03-17T09:39:51.817 に答える