[英]WPF TemplateBinding to DataContext of templated parent
We have four identical popups with grids in four XAML views. 我们在四个XAML视图中有四个相同的带有网格的弹出窗口。 I'd like to move that XAML to a template and apply via a Style to to ContentControls in all four of them.
我想将XAML移至模板,然后通过样式将其应用于所有这四个控件中的ContentControls。 The trouble is passing in the source of the items in the grids.
麻烦在于传递网格中项目的来源。 We get that from each of four different view models.
我们可以从四个不同的视图模型中分别获得。 It's different in each case, the only thing that differs among the four cases.
在每种情况下都不同,唯一的不同是四种情况。 I'll probably end up renaming them consistently, but I'd like to think that's a separate issue.
我可能最终会一致地重命名它们,但是我想这是一个单独的问题。
Obviously I don't understand TemplateBinding at all. 显然我根本不了解TemplateBinding。 How do I bind a property of a child of the template to a property of the ContentControl that I'm applying the template to?
如何将模板子级的属性绑定到要将模板应用到的ContentControl的属性?
Except for the value of the DataSource attribute changing, the XAML for the grid is identical to what works perfectly well when we use it directly. 除了更改DataSource属性的值外,网格的XAML与直接使用时的效果完全一样。
I added the TextBlock just to see if I could bind anything at all. 我添加了TextBlock只是看我是否可以绑定任何东西。 I do get
NaN
there. 我确实在那里找到
NaN
。
<Style x:Key="HistoryPopupContentStyle" TargetType="ContentControl">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text="{TemplateBinding Width,
diag:PresentationTraceSources.TraceLevel=High}"
Background="White"
Foreground="Black"/>
<dxg:GridControl
DataSource="{Binding RelativeSource={RelativeSource
Path=DataContext,
TraceLevel=High}"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
>
<!-- Columns. The grid displays column headers
as desired but with no rows -->
</dxg:GridControl.Columns>
</dxg:GridControl>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<Popup
Name="PopHistory"
DataContext="{Binding Path=HistoryList}"
>
<ContentControl DataContext="{Binding Path=HistoryList}"
Style="{StaticResource HistoryPopupContentStyle}"
Name="Testing"
/>
</Popup>
You will need to subclass ContentControl
(or just Control
), so that you can add new dependency properties. 您将需要子类化
ContentControl
(或者只是Control
),以便可以添加新的依赖项属性。
public class GridControl : ContentControl
{
// TODO add dependency properties
public GridControl()
{
DefaultStyleKey = typeof(GridControl);
}
}
Add your "Items" dependency property to the above control (type IEnumerable
). 将“项目”依赖项属性添加到上述控件中(类型
IEnumerable
)。
Next, update your template to target the new type: 接下来,更新您的模板以定位新类型:
<Style x:Key="HistoryPopupContentStyle" TargetType="local:GridControl">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<dxg:GridControl ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=local:GridControl},Path=Items}" />
Alternately, you could set the "Template" instead of the "ContentTemplate". 或者,您可以设置“模板”而不是“ ContentTemplate”。 This would be when you use
TemplateBinding
: 这将是当您使用
TemplateBinding
:
<Style x:Key="HistoryPopupContentStyle" TargetType="local:GridControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:GridControl">
<dxg:GridControl ItemsSource="{TemplateBinding Items}" />
Use it by binding the Items
property to your source items: 通过将
Items
属性绑定到源项目来使用它:
<local:GridControl Style="{StaticResource HistoryPopupContentStyle}"
Items="{Binding Path=HistoryList}" />
You could also skip creating a subclass altogether, and just use the Content
property of ContentControl
to stash the items: 您也可以完全跳过创建子类,而仅使用
ContentControl
的Content
属性存储项:
<Style x:Key="HistoryPopupContentStyle" TargetType="ContentControl">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<dxg:GridControl ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=local:GridControl},Path=Content}" />
Or using the Template / TemplateBinding approach 或使用Template / TemplateBinding方法
<Style x:Key="HistoryPopupContentStyle" TargetType="ContentControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContentControl">
<dxg:GridControl ItemsSource="{TemplateBinding Content}" />
Use like this: 像这样使用:
<ContentControl Style="{StaticResource HistoryPopupContentStyle}"
Content="{Binding Path=HistoryList}" />
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.