2013-05-21 3 views
9

Я хотел бы установить Button в Content на Path, определенный в Resources. Поэтому я создал UserControl, определил Path, два Brushes и кнопку Style в ресурсах ... и все было в порядке.Путь от ресурсов как содержимое кнопки

<UserControl ...> 
    <UserControl.Resources> 
     <Path x:Key="PageSmallIcon2" Stretch="Fill" Fill="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Control}}, Path=Foreground}" Stroke="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Control}}, Path=Foreground}" SnapsToDevicePixels="True" Data="F1 M 19,25L 27,25L 27,33L 19,33L 19,25 Z M 19,36L 27,36L 27,44L 19,44L 19,36 Z M 31,25L 57,25L 57,33L 31,33L 31,25 Z M 19,47L 27,47L 27,55L 19,55L 19,47 Z "/> 
     <SolidColorBrush x:Key="MainColorBrush2" Color="Orange"/> 
     <SolidColorBrush x:Key="WhiteColorBrush2" Color="WhiteSmoke"/> 
     <Style x:Key="TransparentButtonStyle2" TargetType="{x:Type Button}"> 
      <Setter Property="Foreground" Value="{StaticResource WhiteColorBrush2}"/> 
      <Setter Property="Height" Value="25"/> 
      <Setter Property="Width" Value="25"/> 
      <Setter Property="Template"> 
       <Setter.Value> 
        <ControlTemplate TargetType="{x:Type Button}"> 
         <Grid> 
          <Rectangle Fill="Transparent"/> 
          <ContentPresenter x:Name="contentPresenter" Content="{TemplateBinding Content}" Margin="2" /> 
         </Grid> 
         <ControlTemplate.Triggers> 
          <Trigger Property="IsPressed" Value="True"> 
           <Setter Property="Foreground" Value="{StaticResource MainColorBrush2}"/> 
          </Trigger> 
         </ControlTemplate.Triggers> 
        </ControlTemplate> 
       </Setter.Value> 
      </Setter> 
     </Style> 
    </UserControl.Resources> 
    <Grid> 
     <Button Command="{Binding Path=SmallPageSizeCommand}" Style="{StaticResource TransparentButtonStyle2}" Content="{StaticResource PageSmallIcon2}"/> 
     ... 
    </Grid> 
</UserControl> 

Я решил разместить эти ресурсы отдельно ResourceDictionaries. Я планирую иметь больше Paths и Brushes ... Также я хотел бы иметь только один стиль для кнопки. В основном я это делаю, потому что у меня был стиль для каждой из моих кнопок и Path для каждого конкретного Button был частью этого Button's ControlTemplate.

Так что я создал три ResourceDictionariesColors.xaml, Icons.xaml и Controls.xaml, а затем я обновил App.xaml

<Application.Resources> 
    <ResourceDictionary> 
     <ResourceDictionary.MergedDictionaries> 
      <ResourceDictionary Source="Theme/Colors.xaml"/> 
      <ResourceDictionary Source="Theme/Icons.xaml"/> 
      <ResourceDictionary Source="Theme/Controls.xaml"/> 
     </ResourceDictionary.MergedDictionaries> 
    </ResourceDictionary> 
</Application.Resources> 

Теперь Path «s Fill свойство не обновляется, когда я нажимаю, что Button. Может кто-нибудь объяснить, почему он не работает в отдельном ResourceDictionaries и предоставить мне решение этой проблемы?

UPDATE

Так я обнаружил, что проблема заключается в Path. Когда у меня есть это Path в <UserControl.Resources>, цвета в Colors.xaml и стиль кнопки в Controls.xaml все работает снова.

Я также обнаружил, что, когда у меня есть мой Path в Icons.xaml и я использую его в моем UserControl как содержание баттона

<Button Command="{Binding Path=SmallPageSizeCommand}" Style="{StaticResource TransparentButtonStyle2}" Content="{StaticResource PageSmallIcon2}"/> 

и у меня есть несколько экземпляров моей UserControl ... тогда Path присутствует только в одном экземпляр UserControl за раз.

+0

Все выглядит хорошо для меня. Вы получаете какие-либо ошибки в окне вывода с прикрепленным отладчиком? Пока вы добавляете свой Colors.xaml перед Controls.xaml, вы должны получить желаемые результаты. –

+0

@NovitchiS № Ошибка в окне вывода. –

+2

Вторая проблема из Update заключается в том, что вы даете тот же элемент другим родителям в XAML. Для нескольких «кнопок» вы устанавливаете один и тот же «Путь», определенный как ресурс, как 'Содержимое' кнопки 'Button'. Чтобы решить эту проблему, вы можете пометить ресурс атрибутом 'x: Shared =" False ". В этом случае XAML Parser создаст новый экземпляр элемента Path для каждого Reference. –

ответ

13

Причина:

У меня есть несколько экземпляров моей UserControl ... тогда Путь присутствует только в одном экземпляре UserControl в то время

потому, что вы даете тот же элемент разных родителей в XAML. Вы устанавливаете содержимое нескольких элементов управления Button на PathShape, который определяется ресурсами. Для целей оптимизации каждая ссылка на ресурс будет возвращать по умолчанию тот же экземпляр объекта, и поскольку в WPF каждый элемент может иметь только один родитель за один раз, только последний Button в вашем заявлении XAML будет иметь свой контент, установленный на нужный Path , Чтобы решить эту проблему, вы можете пометить ресурс атрибутом x: Shared = "False". В этом случае XAML Parser создаст новый экземпляр элемента Path для каждого Reference.

+3

Похоже, что это значение по умолчанию - назад. Зачем вам ресурс что-то, если вы не собираетесь делиться им? –

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