В XAML, каково правильное пространство имен XML для VisualStateManager? - PullRequest
3 голосов
/ 06 сентября 2011

Я пытаюсь изменить стиль нескольких кнопок Toggle.Видимо, я не могу просто установить новый цвет фона, потому что есть «Шаблон управления», который обеспечивает визуальное поведение ToggleButton.Итак, что мне нужно сделать, это указать в XAML замену «ControlTemplate» для ToggleButton, которая обеспечивает другое визуальное поведение, помимо простого цвета фона.
Q1 .Это правильно?


Я решил начать с шаблона элемента управления «по умолчанию» для кнопки ToggleButton, который я взял здесь , а затем изменить его.На самом деле это ControlTemplate по умолчанию для Silverlight, я думаю, и я не использую Silverlight, я использую WPF.Но ... Соответствующая страница документации для WPF не содержит спецификацию шаблона элемента управления по умолчанию.Он предоставляет «a» ControlTemplate, что не то, что я хочу.
Q2 .Я не уверен, имеет ли значение, что я использую вещь от Silverlight.Это так?


В примере с Silverlight есть префикс пространства имен XML vsm, примененный к VisualStateManager.Очевидно, пространство имен xml -

  xmlns:vsm = "clr-namespace:System.Windows;assembly=System.Windows"  

... но где-то еще я читал, что это пространство имен XML "больше не нужно".

Это все очень, очень запутанно.

В Googlespace есть ссылки на то, что называется "Инструментарий WPF" , с которым я ранее сталкивался - Я использовал его для текстового поля автозаполнения довыпуск WPF V4.Я предполагаю, что некоторые вещи из набора инструментов WPF были добавлены в WPF для .NET v4.0, и поэтому мне больше не нужно указывать набор инструментов WPF.
Q3 .Если бы кто-то мог подтвердить это понимание, я был бы признателен за это.


Хорошо, теперь, начиная с «ControlTemplate» по умолчанию для ToggleButton, я первым делом должен был скомпилировать его, прежде чем вносить какие-либо изменения.Он не компилируется, завершается с

c: \ dev ... \ ToggleButtonStyle1.xaml (23,14): ошибка MC3074: тег 'VisualStateManager.VisualStateGroups' не существует в пространстве имен XML 'http://schemas.microsoft.com/winfx/2006/xaml/presentation'. Строка 23, Позиция 14.

Достаточно ясно.Затем я посмотрел документацию для определения VisualStateManager в XAML.Это, как ни странно, определяет два пространства имен xml, одно из которых я и использовал.

enter image description here

Q4 Хм, какой из них я должен использовать?Один из них я использовал, и он не работал.В документации совершенно неясно, что означает указание ДВУХ пространств имен XML .(с их головами!)

У меня есть ссылка на PresentationFramework.dll в файле проекта:

  <ItemGroup>
     ....
    <Reference Include="PresentationFramework" />
  </ItemGroup>

Я не использую Visual Studio здесь;Я использую текстовый редактор.Я хочу понять, как это работает, а не какие кнопки нажимать.

Спасибо за любую помощь, которую вы можете оказать.


Просто дополнительный комментарий - все это кажется очень очень сложным.Все, что я хочу сделать, это изменить цвет кнопки ToggleButton, когда он включен.Это действительно не должно быть так сложно.

Ответы [ 2 ]

5 голосов
/ 06 сентября 2011

Вам не нужно указывать пространство имен для VSM (пространство имен http://schemas.microsoft.com/winfx/2006/xaml/presentation является пространством имен WPF по умолчанию, объявленным как xmlns = "..." в большинстве стандартных .xaml) - однако вы можете используйте его только в определенных частях вашей визуальной иерархии.

Например, когда я использую VSM в стандартном UserControl, он выглядит примерно так:

<UserControl x:Class="Whatever"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Grid x:Name="LayoutRoot">
    <VisualStateManager.VisualStateGroups>
      <VisualStateGroup x:Name="CommonStates">
        <VisualState x:Name="Disabled">
          <!-- Storyboards go here -->
        </VisualState>
      </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
  </Grid>
</UserControl>

Размещение VSAM xaml на этом уровне позволит вашим раскадровкам ссылаться на любые элементы, содержащиеся в сетке. Это работает так же в ControlTemplate, как вы работаете с. Однако следует отметить, что, находясь в ваших пользовательских элементах управления, вы можете называть визуальные состояния по своему усмотрению (поскольку в конечном итоге вы будете выполнять вызовы для переключения на это визуальное состояние в коде) с помощью встроенные элементы управления, ваши визуальные состояния должны быть названы в точности так, как ожидает элемент управления.

0 голосов
/ 07 сентября 2011

Отвечая на мой собственный вопрос ....
Q1 ДА
Q2 Нет - это не имеет значения.Шаблоны «примерно» одинаковы.
Q3 Не уверен
Q4 Не знаю.

Ключ был в том, что мне нужноуказать TargetFramework = 4.0.Я компилировал против v3.5, и VSM, по-моему, впервые был доступен в v4.0, так что это стало причиной ошибки «not found in namespace xxxxx».

Мне не нужно было указывать XMLNS в файле XAML.

Шаг назад - ответ на более широкий вопрос - как получить кнопку ToggleButton, которая меняет цвет при нажатии ... Я попытался поиграться со встроенным ControlTemplate, но это было слишком сложно для меня, чтобы понять.Анимации, которые происходили с Press and Checked и так далее - я никогда не мог понять, как заставить его делать то, что я хотел.

Я разобрал шаблон на нечто гораздо большее, без всех градиентов и анимаций, затем добавил несколько анимаций и триггеров, чтобы сделать то, что я хотел.
визуальный эффект таков.ON:

enter image description here

OFF:

enter image description here


XAML, который я использовал:

<ResourceDictionary xmlns     = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x   = "http://schemas.microsoft.com/winfx/2006/xaml">
  <Style x:Key      = "ToggleButtonStyle3"
         TargetType = "ToggleButton">

<!-- This is a style (template?) for a toggle button. I wanted it to
     change to a contrasty color when depressed. This took me a
     loooooong time and much trial and error to figure out. The visual
     effect is somewhat like the buttons in the compile output log in
     Visual Studio, in which you can toggle the display of errors and
     warnings.
-->
    <Setter Property="Background" Value="#FFF7F0D2"/>
    <Setter Property="Foreground" Value="#FF000000"/>
    <Setter Property="Padding" Value="3"/>
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="BorderBrush">
      <Setter.Value>
        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
          <GradientStop Color="#FFC4BC64" Offset="0"/>
          <GradientStop Color="#FFADA658" Offset="0.375"/>
          <GradientStop Color="#FFA19A52" Offset="0.375"/>
          <GradientStop Color="#FF847E43" Offset="1"/>
        </LinearGradientBrush>
      </Setter.Value>
    </Setter>
    <Setter Property="Template">
      <Setter.Value>
        <ControlTemplate TargetType="ToggleButton">
          <Grid x:Name="ButtonGrid">
            <VisualStateManager.VisualStateGroups>
              <VisualStateGroup x:Name="CommonStates">
                <VisualState x:Name="Normal"/>
                <VisualState x:Name="MouseOver">
                  <Storyboard>
                    <DoubleAnimation Duration="0" Storyboard.TargetName="InnerRectangle" Storyboard.TargetProperty="Opacity" To="0.3"/>
                  </Storyboard>
                </VisualState>
                <VisualState x:Name="Pressed">
                  <Storyboard>
                    <ColorAnimation Duration="00:00:00"
                                    Storyboard.TargetName="InnerRectangle"
                                    Storyboard.TargetProperty="(Rectangle.Fill).(SolidColorBrush.Color)"
                                    To="#FFF5BF0F"/>
                  </Storyboard>
                </VisualState>
                <VisualState x:Name="Disabled">
                  <Storyboard>
                    <DoubleAnimation Duration="0" Storyboard.TargetName="DisabledVisualElement" Storyboard.TargetProperty="Opacity" To=".55"/>
                  </Storyboard>
                </VisualState>
              </VisualStateGroup>
              <VisualStateGroup x:Name="CheckStates">
                <VisualState x:Name="Checked">
                  <Storyboard>
                    <ColorAnimation Duration="00:00:00"
                                    Storyboard.TargetName="InnerRectangle"
                                    Storyboard.TargetProperty="(Rectangle.Fill).(SolidColorBrush.Color)"
                                    To="#FFF5D018"/>
                  </Storyboard>
                </VisualState>
                <VisualState x:Name="Unchecked"/>
              </VisualStateGroup>
              <VisualStateGroup x:Name="FocusStates">
                <VisualState x:Name="Focused">
                  <Storyboard>
                    <DoubleAnimation Duration="0" Storyboard.TargetName="FocusVisualElement" Storyboard.TargetProperty="Opacity" To="1"/>
                  </Storyboard>
                </VisualState>
                <VisualState x:Name="Unfocused" />
              </VisualStateGroup>
            </VisualStateManager.VisualStateGroups>

            <Border x:Name          ="ButtonBorder"
                    CornerRadius    ="1"
                    Background      ="{TemplateBinding Background}"
                    BorderThickness ="{TemplateBinding BorderThickness}"
                    BorderBrush     ="{TemplateBinding BorderBrush}">
              <Border x:Name="InnerButtonBorder"
                      CornerRadius="1"
                      BorderThickness="2"
                      Background="#FFFAEB16">
                <Rectangle x:Name="InnerRectangle" Opacity="1" Fill="#F7F0D2" />
              </Border>
            </Border>

            <ContentPresenter
                x:Name="contentPresenter"
                Content="{TemplateBinding Content}"
                ContentTemplate="{TemplateBinding ContentTemplate}"
                VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                TextBlock.Foreground="{TemplateBinding Foreground}"
                Margin="{TemplateBinding Padding}"/>
            <Rectangle x:Name="DisabledVisualElement" RadiusX="3" RadiusY="3" Fill="#FFFFFFFF" Opacity="0" IsHitTestVisible="false" />
            <Rectangle x:Name="FocusVisualElement" RadiusX="2" RadiusY="2" Margin="1" Stroke="#FFD1C44D" StrokeThickness="1" Opacity="0" IsHitTestVisible="false" />
          </Grid>
          <ControlTemplate.Triggers>

            <Trigger Property="ToggleButton.IsChecked" Value="True">
              <!-- This setter hides the desired element when the ToggleButton's initial state is checked -->
              <Setter TargetName="ButtonBorder" Property="Background" Value="#FFF5D018"/>
              <Setter TargetName="contentPresenter" Property="TextBlock.Foreground" Value="#FF000000"/>
            </Trigger>
            <Trigger Property="ToggleButton.IsChecked" Value="False">
              <Setter TargetName="contentPresenter" Property="TextBlock.Foreground" Value="#78999999"/>
            </Trigger>
          </ControlTemplate.Triggers>
        </ControlTemplate>
      </Setter.Value>
    </Setter>
  </Style>
</ResourceDictionary>

Я поместил это в отдельный файл, назовите его ToggleButtonStyle3.xaml.Затем я использую это так:

<Window.Resources>
  <ResourceDictionary>
    <Style ....
    </Style>
    <ResourceDictionary.MergedDictionaries>
      <ResourceDictionary Source="Resources/ToggleButtonStyle3.xaml" />
    </ResourceDictionary.MergedDictionaries>
  </ResourceDictionary>
</Window.Resources>
....

         <ToggleButton Name       ="btnShowAlerts"
                      IsChecked  ="{Binding Path=ShowAlerts, Mode=TwoWay}"
                      Style      ="{StaticResource ToggleButtonStyle3}"
                      Content    ="alerts"
                      FontSize   ="9"
                      Padding    ="8,2"
                      Margin     ="0"
                      ClickMode  ="Press"
                      />

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

...