Привязать ImageBrush к шаблону с помощью DependencyProperty - PullRequest
2 голосов
/ 01 февраля 2011

Я пытаюсь создать специальную кнопку, которая окрашивает изображение на основе цвета переднего плана из системы. Решение, по-видимому, заключается в использовании изображения в качестве маски непрозрачности для получения цвета, и оно работает, когда я устанавливаю изображение прямо так:

<Grid>
  <Rectangle x:Name="ImageForeground" Height="48" Width="48" 
    Fill="{StaticResource PhoneForegroundBrush}" >
    <Rectangle.OpacityMask>
      <ImageBrush Stretch="Fill" ImageSource="/icons/play.png"/>
    </Rectangle.OpacityMask>
  </Rectangle>
</Grid>

Но как только я попробую шаблон это с DependencyProperty для изображения Lite это:

public static readonly DependencyProperty ImageProperty  =
  DependencyProperty.Register("Image", typeof(ImageSource), 
                              typeof(RButton), null);  

А потом в XAML вот так:

<Grid>
  <Rectangle x:Name="ImageForeground" Height="48" Width="48" 
    Fill="{TemplateBinding Foreground}" >
    <Rectangle.OpacityMask>
      <ImageBrush Stretch="Fill" ImageSource="{TemplateBinding Image}"/>
    </Rectangle.OpacityMask>
  </Rectangle>
</Grid>

Я получаю сообщение об ошибке:

object of type 'System.Windows.CustomDependencyProperty' 
  cannot be converted to type 'System.Windows.DependencyProperty'

С ImageProperty все в порядке, так как я тестировал привязку его к изображению, как это

<Image Source="{TemplateBinding Image}" Width="48" Height="48" />

Есть идеи? Моя догадка говорит о том, как я определяю свой DependecyProperty, но я не знаю, как двигаться дальше.

Ответы [ 6 ]

6 голосов
/ 01 февраля 2011

ImageBrush не наследуется от FrameworkElement, поэтому он не может быть TemplateBound или Data Bound.

3 голосов
/ 01 февраля 2011

Я отметил это как ответ, хотя это был не полный ответ.Чтобы все это заработало, мне пришлось немного поработать, поскольку я не могу использовать конвертер в TemplateBinding, вздох ... в любом случае.Вот код, который решил его для меня вместе с конвертером в статье , на которую указал Дерек.

Поэтому, чтобы связать мой Image DependencyProperty как кисть изображений в моем шаблоне, я должен сделатьэто ...

<Grid>
  <Grid.Resources>
    <controls:ImageBrushConverter x:Key="brushConverter"/>
  </Grid.Resources>
  <Rectangle 
    x:Name="ImageForeground"
    Height="48"
    Width="48" 
    Fill="{TemplateBinding Foreground}" 
        DataContext="{TemplateBinding Image}"
        OpacityMask="{Binding Converter={StaticResource brushConverter}}">
  </Rectangle>
</Grid> 

Не очевидно, но это помогло, это многое решило для меня.Спасибо за помощь

3 голосов
/ 01 февраля 2011

Я попытался воспроизвести вашу проблему в тестовом проекте на основе предоставленного вами XAML, и должен признать, что я не столкнулся с проблемой, которую вы описали.Если бы вы могли предоставить код для RButton и некоторый контекст о том, как используется элемент управления, мне бы повезло (или нехватка!).

Был отличный пост в блоге Все оСвойства зависимостей в Silverlight для WP7 , опубликованные сегодня, могут оказаться полезными.

ОБНОВЛЕНИЕ: Я только что прочитал эту идеально подходящую статью , которая полностью объясняет проблему и дает решение.По сути, ImageBrush не является FrameworkElement, поэтому вы не можете использовать TemplateBinding с ним.

2 голосов
/ 03 марта 2014

Вы можете использовать привязку RelativeSource TemplatedParent вместо TemplateBinding. Это в основном то же самое, но оно будет работать в тех странных случаях, когда TemplateBinding не работает.

<ImageBrush
    ImageSource="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Image}" />
0 голосов
/ 21 марта 2013

Или, если вы являетесь автором элемента управления, тогда OnApplyTemplate найдите визуальную кисть в шаблоне и установите ее значение.

public override void OnApplyTemplate()
{
    base.OnApplyTemplate();

    VisualBrush oVBrushBack = (VisualBrush)this.Template.FindName("rectVisual", this);

    oVBrushBack.Visual = this.IconVisual;
}
0 голосов
/ 21 марта 2013

Другой подход, но без необходимости в преобразователе

<Grid>
<Rectangle x:Name="ImageForeground" DataContext="{TemplateBinding Image}" Height="48" Width="48" 
        Fill="{TemplateBinding Foreground}" >
    <Rectangle.OpacityMask>
        <ImageBrush Stretch="Fill" ImageSource="{Binding DataContext , RelativeSource={RelativeSource AncestorType=Rectangle}}"/>
    </Rectangle.OpacityMask>
</Rectangle>

// Или

<Rectangle DataContext="{TemplateBinding IconVisual}" x:Name="Icon" RadiusX="2" RadiusY="2" StrokeThickness="1" Margin="{TemplateBinding Padding}"  Fill="{TemplateBinding Foreground}" Stroke="{TemplateBinding Foreground}" >
                                <Rectangle.OpacityMask>
                                    <VisualBrush Visual="{Binding DataContext , RelativeSource={RelativeSource AncestorType=Rectangle}}"  Stretch="Uniform" />
                                </Rectangle.OpacityMask>
                            </Rectangle>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...