Как сделать цвет элементов WPF DrawingImage динамическим? - PullRequest
7 голосов
/ 09 февраля 2011

Нам нужно, чтобы определенные векторные графические изображения меняли цвет определенных элементов в графике во время выполнения.Казалось бы, установка этих цветов на основе статических или динамических значений ресурсов не будет работать.Мы хотим иметь несколько версий одной и той же графики, каждая из которых имеет возможность устанавливать определенные графические элементы (путь, линия и т. Д.) На разные цвета, поэтому я не думаю, что подход с использованием динамических ресурсов будет работать.Это оставляет привязку данных, что кажется правильным подходом.Мы обновляем графику, чтобы использовать выражение привязки данных вместо жестко заданного цвета кисти, например:

<DrawingImage x:Key="Graphic1">
  <DrawingImage.Drawing>
    <DrawingGroup>
      <DrawingGroup.Children>
        <GeometryDrawing Geometry="F1 M 8.4073,23.9233L">
          <GeometryDrawing.Pen>
            <Pen LineJoin="Round" Brush="{Binding Line1Brush, Mode=OneWay}"/>
          </GeometryDrawing.Pen>
        </GeometryDrawing>
        <GeometryDrawing Geometry="F1 M 3.6875,2.56251L">
          <GeometryDrawing.Pen>
            <Pen LineJoin="Round" Brush="{Binding Line2Brush, Mode=OneWay}"/>
          </GeometryDrawing.Pen>
        </GeometryDrawing>
      </DrawingGroup.Children>
    </DrawingGroup>
  </DrawingImage.Drawing>
</DrawingImage>

Затем мы создаем экземпляр объекта модели представления (поддерживающего INotifyPropertyChanged) для каждого экземпляра Graphic1 в этом случаеи убедитесь, что у него есть свойства Line1Brush и Line2Brush.Звучит хорошо, но я не могу заставить его работать.Я предполагаю, что это изображение, которое само определено в словаре ресурсов для объектов Image, и я пытаюсь установить их DataContext, и я получаю вывод ошибки привязки данных в моем окне отладки.Вот изображение XAML:

<Image x:Name="Pulse1" Grid.Column="0" Source="{StaticResource Graphic1}"/>
<Image x:Name="Pulse2" Grid.Column="1" Source="{StaticResource Graphic1}"/>

И затем в методе Initialize окна я устанавливаю их контекст данных следующим образом:

 public MainWindow()
 {
     InitializeComponent();
     this.DataContext = this;
     this.PulseImage1 = new PulseImageViewModel();
     this.PulseImage2 = new PulseImageViewModel();
     this.PulseImage2.Line1Brush = Brushes.Green;
     this.PulseImage2.Line2Brush = Brushes.Red;
     this.Pulse1.DataContext = this.PulseImage1;
     this.Pulse2.DataContext = this.PulseImage2;
}

Где PulseImageViewModel (показано ниже) определяет двасвойства Line1Brush и Line2Brush, каждое из которых инициирует событие PropertyChanged.

public class PulseImageViewModel : INotifyPropertyChanged
{
    private Brush _line1Brush = Brushes.Yellow;
    private Brush _line2Brush = Brushes.Black;

    public event PropertyChangedEventHandler PropertyChanged;

    public Brush Line1Brush
    {
        get { return _line1Brush; }
        set
        {
            if (_line1Brush != value)
            {
                _line1Brush = value;
                NotifyPropertyChanged("Line1Brush");
            }
        }
    }
    public Brush Line2Brush
    {
        get { return _line2Brush; }
        set
        {
            if (_line2Brush != value)
            {
                _line2Brush = value;
                NotifyPropertyChanged("Line2Brush");
            }
        }
    }

    private void NotifyPropertyChanged(string propertyName)
    {
        var del = PropertyChanged;
        if (del != null)
        {
            del(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

Тем не менее я получаю ошибки привязки данных, указывающие на то, что WPF ищет Line1Brush в объекте MainWindow верхнего уровня, а не в моем объекте PulseImageViewModel.Любые мысли о том, что я делаю не так или есть лучший способ достичь моей цели динамически изменяемых цветов в векторной графике?Кроме того, было бы неплохо, если бы по умолчанию графика могла иметь красивый статический набор цветов, если пользователь не подключил объект модели представления.

1 Ответ

5 голосов
/ 09 февраля 2011

У StaticResource будет DataContext от Window Я верю.Изменится ли это, если вы используете DynamicResource?

Edit Я получаю те же результаты, что и вы, и Snoop не помогает.Даже перемещение DataContext в XAML ничего не меняет.Для забавы я переключился на вставку TextBox в содержимое Label, и вот, ЭТО работает ... Понятия не имею, в чем разница.

<DataTemplate x:Key="Graphic1">
    <Image>
        <Image.Source>
            <DrawingImage>
                <DrawingImage.Drawing>
                    <DrawingGroup>
                        <DrawingGroup.Children>
                            <GeometryDrawing Geometry="F1 M 8.4073,23.9233L">
                                <GeometryDrawing.Pen>
                                    <Pen LineJoin="Round"
                                         Brush="{Binding Line1Brush, Mode=OneWay}" />
                                </GeometryDrawing.Pen>
                            </GeometryDrawing>
                            <GeometryDrawing Geometry="F1 M 3.6875,2.56251L">
                                <GeometryDrawing.Pen>
                                    <Pen LineJoin="Round"
                                         Brush="{Binding Line2Brush, Mode=OneWay}" />
                                </GeometryDrawing.Pen>
                            </GeometryDrawing>
                        </DrawingGroup.Children>
                    </DrawingGroup>
                </DrawingImage.Drawing>
            </DrawingImage>
        </Image.Source>
    </Image>
</DataTemplate>

С XAML, похожим на:

<ContentPresenter ContentTemplate="{StaticResource Graphic1}"
                  Content="{Binding PulseImage1}"
                  Grid.Column="0" />
<ContentPresenter ContentTemplate="{StaticResource Graphic1}"
                  Content="{Binding PulseImage2}"
                  Grid.Column="1" />
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...