2015-05-09 4 views
1

У нас есть различные иконки в виде XAML ресурсов в прикладном что-то вроде этого:WPF: Не в состоянии установить цвет ресурса посредством связывания

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
<DrawingBrush x:Key="My_Icon"> 
    <DrawingBrush.Drawing> 
     <GeometryDrawing Brush="Gray"> <!--I want to set this Brush here using binding--> 
      <GeometryDrawing.Geometry> 
       <GeometryGroup> 
        <EllipseGeometry Center="50,50" RadiusX="45" RadiusY="20" /> 
        <EllipseGeometry Center="50,50" RadiusX="20" RadiusY="45" /> 
       </GeometryGroup> 
      </GeometryDrawing.Geometry> 
     </GeometryDrawing> 
    </DrawingBrush.Drawing> 
</DrawingBrush> 

И мы используем эти ресурсы в другом XAML файл (загрузить этот ресурс в коде позади, обратитесь к приведенной ниже код)

public partial class Window2 : Window 
{ 
    public Window2() 
    { 
     InitializeComponent(); 

     var resource = Application.Current.FindResource("My_Icon"); 
     this.MyBrush = resource as DrawingBrush; 

     NewBrush = Brushes.Blue; 

     this.DataContext = this; 
    } 

    private DrawingBrush _myBrush; 

    public DrawingBrush MyBrush 
    { 
     get { return _myBrush; } 
     set { _myBrush = value; } 
    } 

    private Brush _newBrush; 

    public Brush NewBrush 
    { 
     get { return _newBrush; } 
     set { _newBrush = value; } 
    } 
} 

проблема есть, я не в состоянии установить цвет значка (в коде ресурса, первый фрагмент кода) с помощью связывание с имуществом, которое находится в ViewModel (MyBrush собственности в этом случае в Window2 коде позади)

Я попытался с следующим кодом в файле ресурсы:

<GeometryDrawing Brush="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Rectangle}, Path=NewBrush}"> 

Но это не работает. Что мне здесь не хватает.

+0

Вы включили в словарь ресурсов? – Caramiriel

+0

Да. Это я и сделал. Это рабочий образец с серым цветом, который я установил. Все, что я хочу сделать, это установить этот цвет с привязкой. – Randeep

+0

Я не уверен, что вы пытаетесь сделать здесь. Судя по вашему последнему фрагменту кода, вы пытаетесь связать свойство 'GeomertyDrawing.Brush' с свойством' Window2.MyBrush', которое содержит '" ', который, в свою очередь, является родителем «GeometryDrawing» - это приводит к циклической зависимости и, безусловно, приведет к исключению ... – Grx70

ответ

1

У меня есть два способа решить вашу проблему.

Решение Я (лучше на мой взгляд)

Брось свой код-за подход и импортировать словарь ресурсов непосредственно в окне ресурсов и использовать StaticResourceExtension для ссылки на ресурс:

<Window.Resources> 
    <ResourceDictionary> 
     <ResourceDictionary.MergedDictionaries> 
      <ResourceDictionary Source="TheNameOfYourDictionary.xaml"/> 
     </ResourceDictionary.MergedDictionaries> 
    </ResourceDictionary> 
</Window.Resources> 
... 
<Rectangle Fill="{StaticResource My_Icon}"/> 

Когда вы это сделаете и используете AncestorType=local:Window2, ваша привязка должна работать (хотя в текущей форме последующие изменения в NewBrush свойство не будут отражены в чертеже - обратитесь к списку в конце этого ответа). Обратите внимание, что необходимо использовать {StaticResource My_Icon} вместо {Binding MyBrush}.

Solution II

Установить привязку в коде-за:

var resource = Application.Current.FindResource("My_Icon"); 
this.MyBrush = resource as DrawingBrush; 

NewBrush = Brushes.Blue; 

BindingOperations.SetBinding(MyBrush.Drawing, GeometryDrawing.BrushProperty, 
    new Binding { Path = new PropertyPath("NewBrush"), Source = this }); 

Обратите внимание, что для того, чтобы это (или первый раствор) для работы одного из этих условий должны быть удовлетворены:

  1. NewBrush устанавливается до связывания устанавливается (перед DataContext устанавливается в случае первого раствора)
  2. Window2 реализует INotifyPropertyChanged и PropertyChanged событие возникает после того, как NewBrush установлен
  3. NewBrush свойство зависимостей
+0

Спасибо за ответ, я бы пошел на второй подход, потому что мы загружаем разные ресурсы во время выполнения для разных условий (разные значки для разных типов сущностей). Поэтому я могу ссылаться на отдельный ресурс каждый раз. Как вы думаете, я все еще могу сделать это с Решением I, которое вы дали. Кроме того, должен ли я иметь нулевую проверку для чертежа в ресурсе, может быть, для некоторых ресурсов у меня нет чертежа. И если да, то как поставить эту нулевую проверку. – Randeep

+0

Есть небольшая проблема, с которой я сталкиваюсь: если я снимаю код привязки Brush в ресурсе, я получаю ошибку. i. е. если я изменяю до Я получаю эту ошибку: «Невозможно установить свойство на объект». Windows.Media.GeometryDrawing ', потому что он находится в состоянии только для чтения. " – Randeep

+1

@DotnetRocks Что касается вашего первого комментария - если вы имеете в виду динамическое обращение к различным ресурсам на основе некоторых условий, то это можно сделать в XAML - см. [Триггеры стилизации] (https://msdn.microsoft.com/en-us/ библиотека/ms745683% 28v = vs.110% 29.aspx # styling_triggers). Что касается второй проблемы, это происходит потому, что, если вы не установите привязку в 'GeometryDrawing', она возвращается, как уже упоминалось, в состоянии« только для чтения ». Обходным путем было бы использовать модифицируемую копию «DrawingBrush», полученную методом «Clone()», то есть ресурс MyBrush = ((DrawingBrush)) .Clone(); ' – Grx70

Смежные вопросы