2010-08-19 5 views
1

현재 처리 할 수있는 최선의 방법이 무엇인지 확신 할 수없는 시나리오에 직면하고 있습니다.VisualState 변경 내용을 전파하는 가장 좋은 방법

시나리오 :

  1. ControlA 2 개의 사용자 정의 visualstates,의는 "StateOn"와 "StateOff"그들에게 전화 할 수 있습니다.
  2. 이제 ControlA에 템플릿을 적용하고 "templateA"라고 부르 자.
  3. "templateA"에는 ControlB 유형의 컨트롤이 하나 있습니다 (누가 StateOn/Off를 인식하지 못합니다).
  4. ControlB에는 ControlA의 visualstate 변경 사항, 즉 StateOn 및 StateOff를 처리하는 템플릿이 있습니다.

문제 :
ControlB가 VisualStates 변경 따라서 시각적 인 변화가 발생하지 않는 문제 ControlA에 해고받지 않습니다.

나는이 문제가 루트 요소가 원하는 상태에 대해 불만을 일으키지 않는 컨트롤 (ControlB)과 관련이 있다고 생각한다. 그러나 ControlB의 visualstate 변경 내용을 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> 

코드 : 모든 ControlA 및 ControlB 모두의

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

에 오신 것을 환영합니다 : - m_isSet 필드가 더 이상 필요하면 원래 ControlA 코드로

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

-이 종속성 속성이 모두 컨트롤에 추가로 그러나 당신은 지금 템플릿 바인딩을 통해 속성 값을 전파 할 수 있습니다 그래서, FAQ와 Markdown 문서 (질문을 수정할 때 유용한 마디가 오른쪽 여백에 있음)를 읽으십시오. – AnthonyWJones

답변

0

먼저 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); 
    } 

당신의 직감과는 대조적으로 시각적 상태는 전혀 전파되지 않습니다. 주정부는 직접적으로 첨부 된 통제에 대해서만 의미가 있습니다.

public void ToggleState() 
{ 
    IsSet = !IsSet; 
} 
관련 문제