我的蛋糕也吃了它:绑定容器和它的内容
我有一个自定义控件Cake,它包含两个名为Slice和Filling的DependencyProperties。 如何创建一种让我可以使用切片的风格,同时也让我设计切片?我的蛋糕也吃了它:绑定容器和它的内容
<Style TargetType={x:Type local:Cake}>
//I don't like setting DataContext Here
<Setter Property="DataContext" Value="{Binding RelativeSource={RelativeSource Self}}/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType={x:Type local:Cake}>
<Grid DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}">
//This is how I display a slice
<ContentPresenter Content={Binding Slice}/>
//This is how cake decorations are displayed
<ItemsPresenter/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Slice">
<Setter.Value>
//Design Slice Here - it's easy to override when I want
<Slice Filling={Binding Filling}> // it's just in a setter.
</Setter.Value>
</Setter>
<Setter Property="DataContext" Value="{Binding RelativeSource={RelativeSource Self}}/>
</Style>
选项我已经试过:
我不能使用一个用户控件,因为我想允许指定的内容,这显然不符合用户控件工作。见Here.
我不喜欢上面的例子,因为我必须设置的DataContext蛋糕容器的自我,这就意味着用户不能使用的DataContext为他们 绑定。
我无法使用RelativeSource绑定Filling属性,因为有几个 的蛋糕,Style将不知道哪一个是正确的父级。见 Here.
我可以用一个片元素, 直接更换内容呈现,但因为它是一个模板,我松访问切片任何地方 模板之外。虽然我可能会将视觉树切成片,但这感觉是一场维护噩梦。
我基本上希望每个蛋糕有一个切片,并用
<Cake.Slice>
<DockPanel>
<Rectangle Background= “Blue”/>
<Rectangle Background= “Blue”/>
<Rectangle Background=“{Binding Filling}”/>
</DockPanel>
</Cake.Slice>
同时也给它一个默认外观要能设置。
编辑: 显然,我的风格不工作,前提是我引用Cake.dll,而不是蛋糕项目。为什么会这样?
这不会正是你所需要的,但我希望它会给你指示如何实现这一点。
首先,你并不需要设置DataContext
到控制本身,你可以从蛋糕的控件模板使用{TemplateBinding Slice}
绑定属性蛋糕上的控制(灌装切片),这仅仅是{Binding Slice, RelativeSource={RelativeSource TemplatedParent}}
快捷方式(这样你就可以使用一个或另一个)。
这将是您的控件的简化版本,因为我不知道ControlTemplate中的ItemPresenter应显示哪些项目,或者您的Slice和Filling属性的类型是什么。在这个例子中,Filling是SolidColorBrush
,而Slice是Style
。该样式适用于Cake的ControlTemplate
中的ContentControl
,因此您可以为切片预定义样式,并应用填充选项(如果Slice属性具有不同的用途,则可以引入另一个属性,例如SliceStyle)。
蛋糕控制:
public class Cake : Control
{
static Cake()
{
DefaultStyleKeyProperty.OverrideMetadata(
typeof(Cake),
new FrameworkPropertyMetadata(typeof(Cake)));
}
public SolidColorBrush Filling
{
get { return (SolidColorBrush)GetValue(FillingProperty); }
set { SetValue(FillingProperty, value); }
}
public static readonly DependencyProperty FillingProperty =
DependencyProperty.Register(
"Filling",
typeof(SolidColorBrush),
typeof(Cake),
new PropertyMetadata(Brushes.Transparent));
public Style Slice
{
get { return (Style)GetValue(SliceProperty); }
set { SetValue(SliceProperty, value); }
}
public static readonly DependencyProperty SliceProperty =
DependencyProperty.Register(
"Slice",
typeof(Style),
typeof(Cake),
new PropertyMetadata(null));
}
默认风格(Generic.xaml):
<Style TargetType="{x:Type local:Cake}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:Cake}">
<ContentControl Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
Style="{TemplateBinding Slice}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
不同的切片风格(这些设置控件模板为ContentControl中,这样你就不会打在发行数3你的问题):
<Window.Resources>
<Style x:Key="TwoLayeredSlice" TargetType="{x:Type ContentControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Rectangle Fill="{Binding Filling,
RelativeSource={RelativeSource AncestorType={x:Type local:Cake}}}"/>
<Rectangle Fill="Brown"
Grid.Row="1"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="FourLayeredSlice" TargetType="{x:Type ContentControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Rectangle Fill="{Binding Filling,
RelativeSource={RelativeSource AncestorType={x:Type local:Cake}}}"/>
<Rectangle Fill="Brown"
Grid.Row="1"/>
<Rectangle Fill="{Binding Filling,
RelativeSource={RelativeSource AncestorType={x:Type local:Cake}}}"
Grid.Row="2"/>
<Rectangle Fill="Brown"
Grid.Row="3"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
而在使用中的控制:
<Grid Background="Gray">
<local:Cake Width="200"
Height="100"
HorizontalAlignment="Left"
Filling="Gold"
Slice="{StaticResource TwoLayeredSlice}"/>
<local:Cake Width="200"
Height="100"
HorizontalAlignment="Center"
Filling="Pink"
Slice="{StaticResource FourLayeredSlice}"/>
<local:Cake Width="200"
Height="100"
HorizontalAlignment="Right"
Filling="Blue"
Slice="{StaticResource FourLayeredSlice}"/>
</Grid>
个饱!
虽然这仍然不能直接访问该切片,但它还是让我设计它的一个**梦幻般的工作 - 感谢您找到一种使用RelativeSource的方法! – bwall
你有没有想要在蛋糕中实现的图片? –
@AyyappanSubramanian是的,只是加了一个。 – bwall