Style
中的 常规:,是否可以从MySecondProperty
中绑定到另一个DependencyProperty(例如<Setter Property="MyFirstProperty">
)值?
出于什么目的?要完成以下任务:
1。)导出一些MyButton : Button
控件,该控件上有一个额外的List<string> FlyoutSource
依赖属性。
2.。)定义MyButtonStyle
,其中<Setter Property="Flyout">
元素定义Button.Flyout
属性(自MyButton : Button
起)。
Flyout
中会有ListView
,其ItemsSource
必须绑定到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>
我希望如何使用该解决方案:
<local:MyButton
FlyoutSource="{x:Bind FlyoutSourceList, Mode=TwoWay}"
Style="{StaticResource MyButtonStyle}">
</local:MyButton
更多细节: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 :(得分:1)
您实际上并不需要将Button子类化为此,只需将FlyoutSource作为附加属性即可。
你不能在这里使用RelativeSource模式TemplatedParent,因为它不在ControlTemplate中。
似乎弹出内容从其附加元素获取信息的唯一方法是通过DataContext继承。我只想出这个,但它涉及很多有约束力的体操。我不推荐它。
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));
}
<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>
如果你想继承Button,那么你可以这样做。
<强> 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;
}
}
<强>主题\ Generic.xaml 强>
<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" },
};
}
}
如果我们不必复制整个默认的Button样式,那就太好了。