2016-11-04 5 views
0

일반 스타일 내에 바인딩 :를 지정하는 제어 Style에서 그것은 <Setter Property="MyFirstProperty"> 내에서 (예를 들어, MySecondProperty) 값 다른 DependencyProperty에 결합 할 수있다?UWP 유래 버튼 :

어떤 목적으로? 다음을 수행하려면

1. MyButton : Button 컨트롤을 파생시킵니다.이 컨트롤에는 추가로 List<string> FlyoutSource 종속성 속성이 있습니다.

2.) MyButtonStyle을 정의하십시오. <Setter Property="Flyout"> 요소는 Button.Flyout 속성을 정의합니다 (이후 MyButton : Button).

<local:MyButton 
    FlyoutSource="{x:Bind FlyoutSourceList, Mode=TwoWay}" 
    Style="{StaticResource MyButtonStyle}"> 
</local:MyButton 

더 많은 세부 사항 : :

Flyout 내가 솔루션을 사용하고자하는 방법 MyButton.FlyoutSource

<Style TargetType="local:MyButton" x:Key="MyButtonStyle"> 
    <Setter Property="Background" Value="Green"/> 
    <Setter Property="Flyout"> 
     <Setter.Value> 
      <Flyout> 
       <!-- &&&&&&& THE FOLLOWING LINE DOES NOT WORK PROPERLY &&&&&&& --> 
       <ListView ItemsSource="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=FlyoutSource}"> 
        <ListView.ItemTemplate> 
         <DataTemplate> 
          <TextBlock Text="{Binding}"/> 
         </DataTemplate> 
        </ListView.ItemTemplate> 
       </ListView> 
      </Flyout> 
     </Setter.Value> 
    </Setter> 
</Style> 

에 바인딩해야 그 ItemsSource, 그것의 ListView이됩니다 MyButton에 등급 :

public class MyButton : Button 
{ 
    public MyButton() 
    { 
     this.DefaultStyleKey = typeof(Button); 
    } 

    public static DependencyProperty FlyoutSourceProperty = DependencyProperty.Register(
    "FlyoutSource", typeof(List<string>), typeof(MyButton), 
    new PropertyMetadata(null, new PropertyChangedCallback(OnFlyoutSourceChanged))); 

    public List<string> FlyoutSource 
    { 
     get { return (List<string>)GetValue(FlyoutSourceProperty); } 
     set { SetValue(FlyoutSourceProperty, value); } 
    } 

    public static void OnFlyoutSourceChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) 
    { 
     Debug.WriteLine(""); 
    } 
} 
+0

나는 당신이 여기에서 묻는 무엇을 잘 모른다.모든 또는 특정 버튼 인스턴스에 표준 플라이 아웃 템플릿을 적용하는 방법을 묻는 것입니다. 같은 종류의 ....'

+0

질문 업데이트. 궁극적으로, 나는'Button'에서 파생 된 컨트롤을 만들려고하지만,'ItemsSource'가 내 사용자 정의 버튼의 DP에 바인딩 된 ListView를 포함하는 플라이 아웃을 만듭니다. – bunkerdive

답변

0

FlyoutSource를 첨부 된 속성으로 만들려면 Button을 하위 클래스로 만들 필요가 없습니다.

RelativeSource 모드 TemplatedParent는 ControlTemplate에 없으므로 여기에서 사용할 수 없습니다.

플라이 아웃 콘텐츠가 연결된 요소에서 정보를 얻는 유일한 방법은 DataContext 상속을 사용하는 것입니다. 나는 이걸 가지고 올 수 있었지만 구속력있는 체조를 많이 포함한다. 나는 그것을 추천하지 않는다.

<Grid x:Name="MyGrid"> 
    <Grid.Resources> 
     <Style x:Key="FlyoutButton" TargetType="Button"> 
      <Setter Property="Flyout"> 
       <Setter.Value> 
        <Flyout> 
         <ListView ItemsSource="{Binding (local:ViewProps.FlyoutListSource)}"/> 
        </Flyout> 
       </Setter.Value> 
      </Setter> 
     </Style> 
    </Grid.Resources> 

    <Button 
     Style="{StaticResource FlyoutButton}" 
     Content="Button" 
     DataContext="{Binding RelativeSource={RelativeSource Self}}" 
     local:ViewProps.FlyoutListSource="{Binding ElementName=MyGrid, Path=DataContext.ItemsSource}"/> 
</Grid> 

당신이 버튼을 서브 클래스하려면

public class ViewProps 
{ 
    public static object GetFlyoutListSource(DependencyObject obj) 
    { 
     return (object)obj.GetValue(FlyoutListSourceProperty); 
    } 

    public static void SetFlyoutListSource(DependencyObject obj, object value) 
    { 
     obj.SetValue(FlyoutListSourceProperty, value); 
    } 

    public static readonly DependencyProperty FlyoutListSourceProperty = 
     DependencyProperty.RegisterAttached("FlyoutListSource", typeof(object), typeof(ViewProps), new PropertyMetadata(null)); 
} 

, 그럼 당신은 이런 식으로 뭔가를 할 수 있습니다. generic.xaml을 \

ListFlyoutButton.cs

public sealed class ListFlyoutButton : Button 
{ 
    public object ItemsSource 
    { 
     get { return (object)GetValue(ItemsSourceProperty); } 
     set { SetValue(ItemsSourceProperty, value); } 
    } 

    public static readonly DependencyProperty ItemsSourceProperty = 
     DependencyProperty.Register("ItemsSource", typeof(object), typeof(ListFlyoutButton), new PropertyMetadata(null)); 

    public ListFlyoutButton() 
    { 
     this.DefaultStyleKey = typeof(ListFlyoutButton); 
    } 

    protected override void OnApplyTemplate() 
    { 
     base.OnApplyTemplate(); 

     ((FrameworkElement)((Flyout)Flyout).Content).DataContext = this; 
    } 
} 

테마

<ResourceDictionary 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="***"> 

    <Style TargetType="local:ListFlyoutButton"> 
     <Setter Property="Background" Value="{ThemeResource ButtonBackground}" /> 
     <Setter Property="Foreground" Value="{ThemeResource ButtonForeground}" /> 
     <Setter Property="BorderBrush" Value="{ThemeResource ButtonBorderBrush}" /> 
     <Setter Property="BorderThickness" Value="{ThemeResource ButtonBorderThemeThickness}" /> 
     <Setter Property="Padding" Value="8,4,8,4" /> 
     <Setter Property="HorizontalAlignment" Value="Left" /> 
     <Setter Property="VerticalAlignment" Value="Center" /> 
     <Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" /> 
     <Setter Property="FontWeight" Value="Normal" /> 
     <Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" /> 
     <Setter Property="UseSystemFocusVisuals" Value="True" /> 
     <Setter Property="FocusVisualMargin" Value="-3" /> 
     <Setter Property="Flyout"> 
      <Setter.Value> 
       <Flyout> 
        <ListView ItemsSource="{Binding ItemsSource}"/> 
       </Flyout> 
      </Setter.Value> 
     </Setter> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="local:ListFlyoutButton"> 
        <Grid x:Name="RootGrid" Background="{TemplateBinding Background}"> 
         <VisualStateManager.VisualStateGroups> 
          <VisualStateGroup x:Name="CommonStates"> 
           <VisualState x:Name="Normal"> 
            <Storyboard> 
             <PointerUpThemeAnimation Storyboard.TargetName="RootGrid" /> 
            </Storyboard> 
           </VisualState> 
           <VisualState x:Name="PointerOver"> 
            <Storyboard> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid" Storyboard.TargetProperty="Background"> 
              <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBackgroundPointerOver}" /> 
             </ObjectAnimationUsingKeyFrames> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="BorderBrush"> 
              <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBorderBrushPointerOver}" /> 
             </ObjectAnimationUsingKeyFrames> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground"> 
              <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonForegroundPointerOver}" /> 
             </ObjectAnimationUsingKeyFrames> 
             <PointerUpThemeAnimation Storyboard.TargetName="RootGrid" /> 
            </Storyboard> 
           </VisualState> 
           <VisualState x:Name="Pressed"> 
            <Storyboard> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid" Storyboard.TargetProperty="Background"> 
              <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBackgroundPressed}" /> 
             </ObjectAnimationUsingKeyFrames> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="BorderBrush"> 
              <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBorderBrushPressed}" /> 
             </ObjectAnimationUsingKeyFrames> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground"> 
              <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonForegroundPressed}" /> 
             </ObjectAnimationUsingKeyFrames> 
             <PointerDownThemeAnimation Storyboard.TargetName="RootGrid" /> 
            </Storyboard> 
           </VisualState> 
           <VisualState x:Name="Disabled"> 
            <Storyboard> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid" Storyboard.TargetProperty="Background"> 
              <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBackgroundDisabled}" /> 
             </ObjectAnimationUsingKeyFrames> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="BorderBrush"> 
              <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBorderBrushDisabled}" /> 
             </ObjectAnimationUsingKeyFrames> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground"> 
              <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonForegroundDisabled}" /> 
             </ObjectAnimationUsingKeyFrames> 
            </Storyboard> 
           </VisualState> 
          </VisualStateGroup> 
         </VisualStateManager.VisualStateGroups> 
         <ContentPresenter x:Name="ContentPresenter" 
           BorderBrush="{TemplateBinding BorderBrush}" 
           BorderThickness="{TemplateBinding BorderThickness}" 
           Content="{TemplateBinding Content}" 
           ContentTransitions="{TemplateBinding ContentTransitions}" 
           ContentTemplate="{TemplateBinding ContentTemplate}" 
           Padding="{TemplateBinding Padding}" 
           HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" 
           VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" 
           AutomationProperties.AccessibilityView="Raw" /> 
        </Grid> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
</ResourceDictionary> 

에서 MainPage.xaml

<local:ListFlyoutButton Content="Button" ItemsSource="{Binding Items}"/> 

MainPage.xaml.cs를

public sealed partial class MainPage : Page 
{ 
    public MainPage() 
    { 
     this.InitializeComponent(); 
     DataContext = new 
     { 
      Items = new[] { "Apple", "Banana" }, 
     }; 
    } 
} 

우리는 전체 기본 버튼 스타일을 복제하지 않은 경우 그것은 좋은 것입니다.