2010-08-19 1 views
1

В настоящее время я сталкиваюсь со сценарием, который я не уверен в том, как лучше всего обращаться.Лучший способ распространения изменений VisualState

Сценарий:

  1. ControlA имеет 2 два пользовательских visualstates, давайте называть их «StateOn» и «StateOff».
  2. Теперь применим шаблон для ControlA, назовем его «templateA».
  3. "templateA" имеет один элемент управления под ним типа ControlB (кто не знает StateOn/Off).
  4. ControlB имеет шаблон, который обрабатывает изменения в visualstate ControlA, а именно StateOn и StateOff.

Проблема:
ControlB не получает изменения в VisualStates обстрелял ControlA, таким образом, никаких визуальных изменений не произошло.

Я думаю, что проблема связана с тем, что корневой элемент является элементом управления (ControlB), который не активирует gotostate в желаемых состояниях. Тем не менее, мне интересно, что является самым простым/чистым способом распространения изменений VisualA ​​управления ControlA на ControlB.

Благодарим за помощь!

Генри

Xaml: -

<UserControl x:Class="VisualStateChangePropagation.MainPage" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:local="clr-namespace:VisualStateChangePropagation" 
    mc:Ignorable="d" 
    d:DesignHeight="300" d:DesignWidth="400"> 

    <Grid x:Name="LayoutRoot" Background="White"> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="20"/> 
      <ColumnDefinition Width="50"/> 
      <ColumnDefinition Width="20"/> 
     </Grid.ColumnDefinitions> 
     <Grid.Resources> 

      <SolidColorBrush x:Name="Fill_Bg_Red" Color="Red"/> 
      <SolidColorBrush x:Name="Fill_Bg_Blue" Color="Blue"/> 

      <ControlTemplate x:Name="templateA" TargetType="Control"> 
       <Grid> 
        <VisualStateManager.VisualStateGroups> 
         <VisualStateGroup x:Name="Common"> 
          <VisualState x:Name="StateOn"> 
           <Storyboard> 
            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="m_rect" 
                    Storyboard.TargetProperty="(Rectangle.Fill)"> 
             <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource Fill_Bg_Red}" /> 
            </ObjectAnimationUsingKeyFrames> 
           </Storyboard> 
          </VisualState> 
          <VisualState x:Name="StateOff"/> 
         </VisualStateGroup> 
        </VisualStateManager.VisualStateGroups> 
        <Rectangle x:Name="m_rect" Fill="{StaticResource Fill_Bg_Blue}"/> 
       </Grid> 
      </ControlTemplate> 

      <ControlTemplate x:Name="templateB" TargetType="Control"> 
       <local:ControlB Template="{StaticResource templateA}"/> 
      </ControlTemplate> 

     </Grid.Resources> 
     <local:ControlA x:Name="m_control1" Template="{StaticResource templateA}" Grid.Column="0"/> 
     <Button Click="Button_Click" Grid.Column="1" Content="swap"/> 
     <local:ControlA x:Name="m_control2" Template="{StaticResource templateB}" Grid.Column="2"/> 
    </Grid> 
</UserControl> 

код позади:

public class ControlA : Control 
{ 
    public void ToggleState() 
    { 
     m_isSet = !m_isSet; 
     UpdateVisualState(); 
    } 

    private void UpdateVisualState() 
    { 
     string targetState = m_isSet ? "StateOn" : "StateOff"; 
     VisualStateManager.GoToState(this, targetState, false); 
    } 

    private bool m_isSet = false; 
} 

public class ControlB : Control 
{ 

} 
+0

Добро пожаловать к SO, пожалуйста, прочитайте часто задаваемые вопросы и документацию Markdown (полезный synposis, который доступен в правом поле при редактировании вопроса). – AnthonyWJones

ответ

0

Прежде всего, как ControlA и ControlB должны иметь Dependency Property для IsSet.

public bool IsSet 
    { 
     get { return (bool)GetValue(IsSetProperty); } 
     set { SetValue(IsSetProperty, value); } 
    } 

    public static readonly DependencyProperty IsSetProperty = 
      DependencyProperty.Register(
        "IsSet", 
        typeof(bool), 
        typeof(ControlA), //Change in ControlB 
        new PropertyMetadata(false, OnIsSetPropertyChanged)); 

    private static void OnIsSetPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     Control source = d as Control; 
     string newState = (bool)e.NewValue ? "StateOn" : "StateOff"; 
     VisualStateManager.GotoState(source, newState, true); 
    } 

В отличие от вашей интуиции визуальные состояния не распространяются вообще. Государства имеют смысл только для контроля, к которому они непосредственно привязаны. Однако с этим свойством зависимости добавляется в оба управления теперь могут распространяться значение свойства с помощью привязки шаблона: -

 <ControlTemplate x:Name="templateB" TargetType="Control"> 
      <local:ControlB Template="{StaticResource templateA}" IsSet="{TemplateBinding IsSet}" /> 
     </ControlTemplate> 

Как для вас исходный код ControlA m_isSet поле больше не требуется: -

public void ToggleState() 
{ 
    IsSet = !IsSet; 
}