我正在尝试创建一个非常灵活的自定义控件。我试图实现的灵活性,以便能够将UserControl
绑定到ExpanderContent
Dependency
属性,代码隐藏在代码段后面:
public partial class ChartBar : UserControl
{
public UIElement ExpanderContent
{
get { return (UIElement)GetValue(ExpanderContentProperty); }
set { SetValue(ExpanderContentProperty, value); }
}
// Using a DependencyProperty as the backing store for ExpanderContent. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ExpanderContentProperty =
DependencyProperty.Register("ExpanderContent", typeof(UIElement), typeof(ChartBar), new PropertyMetadata(null, OnExpanderContentChanged));
private static void OnExpanderContentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
//throw new NotImplementedException();
}
.
.
.
我尝试在XAML中使用ContentPresenter
,但它不起作用。我显然可以填充按钮,它可以工作,但这会通过绑定来破坏动态内容。
<Expander x:Name="expander" Header="" VerticalAlignment="Top" d:LayoutOverrides="Width" Style="{DynamicResource ExpanderStyle1}">
<ContentPresenter Content="{Binding ExpanderContent, ElementName=TestControlWithContent}" />
<!--<WrapPanel HorizontalAlignment="Center" >
<Button Content="A" Style="{DynamicResource ButtonStyle1}" />
<Button Content="B" Style="{DynamicResource ButtonStyle1}" />
<Button Content="C" Style="{DynamicResource ButtonStyle1}" />
<Button Content="D" Style="{DynamicResource ButtonStyle1}" />
<Button Content="E" Style="{DynamicResource ButtonStyle1}" />
<Button Content="F" Style="{DynamicResource ButtonStyle1}" />
</WrapPanel>-->
</Expander>
我能做什么更令人困惑
// ChartBarParent is the name of the custom control set in XAML
ChartBarParent.Content = new TestControlWithContent();
它可以解决回调问题。
最终,依赖属性中是UIElement
并使用ContentPresenter
正确的方法来执行此操作吗?
答案 0 :(得分:1)
尝试将ContentPresenter更改为ContentControl。
此外,您可以将UserControl包装在DataTemplate中,并将其设置为ContentControl.ContentTemplate,允许您通过ContentControl.Content属性传递数据上下文。
答案 1 :(得分:0)
以下是我将如何做到这一点。它依赖于urlpatterns = [
url(r'^$', TemplateView.as_view(template_name='base.html'), name="home"),
url(r'^(?P<user_url>[\w.-]+)/', include('imagestore.urls', namespace='imagestore')),
url(r'^(?P<user_url>[\w.-]+)/', include('profiles.urls', namespace='profiles_username')),
]
是UI的东西(如下面“用法”中的第二个示例),或者是具有隐式SecondaryContent
的viewmodel。我可以轻松添加DataTemplate
属性,以便让消费者更明确地控制模板的发生方式。
ChartBar.cs
SecondaryDataTemplateSelector
public class ChartBar : ContentControl
{
static ChartBar()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(ChartBar),
new FrameworkPropertyMetadata(typeof(ChartBar)));
}
// Rather than ExpanderContent, we're inheriting ContentControl.Content for the
// main control content.
#region SecondaryContent Property
public Object SecondaryContent
{
get { return (Object)GetValue(SecondaryContentProperty); }
set { SetValue(SecondaryContentProperty, value); }
}
public static readonly DependencyProperty SecondaryContentProperty =
DependencyProperty.Register("SecondaryContent", typeof(Object), typeof(ChartBar),
new PropertyMetadata(null));
#endregion SecondaryContent Property
#region IsExpanded Property
// This is optional. I just know I'd end up wanting it.
public bool IsExpanded
{
get { return (bool)GetValue(IsExpandedProperty); }
set { SetValue(IsExpandedProperty, value); }
}
public static readonly DependencyProperty IsExpandedProperty =
DependencyProperty.Register("IsExpanded", typeof(bool), typeof(ChartBar),
new PropertyMetadata(false));
#endregion IsExpanded Property
}
,或者Themes/Generic.xaml
中的App.xaml,或者其中一个包含的其他.xaml资源字典。
<Application.Resources>
用法:
<ControlTemplate x:Key="ChartBarDefaultTemplate" TargetType="local:ChartBar">
<!--
Use Binding/RelativeSource TemplatedParent on IsExpanded so it updates both ways,
or remove that attribute/binding if you're not bothering with the IsExpanded DP.
-->
<Expander
x:Name="expander"
Header=""
VerticalAlignment="Top"
Style="{DynamicResource ExpanderStyle1}"
IsExpanded="{Binding IsExpanded, RelativeSource={RelativeSource TemplatedParent}}"
>
<StackPanel Orientation="Vertical">
<ContentPresenter />
<ContentControl
Content="{TemplateBinding SecondaryContent}"
/>
</StackPanel>
</Expander>
</ControlTemplate>
<Style TargetType="local:ChartBar">
<Setter
Property="Template"
Value="{StaticResource ChartBarDefaultTemplate}"
/>
</Style>