WPF - 绑定数据模板

WPF - Binding data template

我正在尝试在 Telerik RadDiagram ShapeStyle 上绑定 <DataTemplate>

<telerik:RadDiagram x:Name="Diagram"
                            ShapeStyle="{StaticResource NodeStyle}"
                            GraphSource="{Binding GraphSource}"/>

此样式如下所示:

    <Grid.Resources>
        <Style x:Key="NodeStyle" TargetType="telerik:RadDiagramShape">
            <Setter Property="Position" Value="{Binding Position, Mode=TwoWay}" />
            <Setter Property="Content" Value="{Binding}" />
            <Setter Property="Geometry" Value="{telerik:CommonShape ShapeType=RectangleShape}" />
            <Setter Property="ContentTemplate" >
                <Setter.Value>
                    <MultiBinding Converter="{StaticResource StyleConverter}">
                        <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=UserControl}"/>
                        <Binding Path=""/>
                    </MultiBinding>
                </Setter.Value>
            </Setter>
        </Style>
...
</Grid.Resources>

样式转换器:

class StyleConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        FrameworkElement targetElement = values[0] as FrameworkElement;

        if (values[0] is BilledMsisdnViewModel)
            return targetElement.FindResource("BilledMsisdnControl");
        else if(values[0] is BilledImeiViewModel)
            return targetElement.FindResource("ImeiControl");

        return null;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

这些资源(BilledMsisdnControl 和 ImeiControl)在 <UserControl.Resources>:

中定义
<UserControl.Resources>
    <ResourceDictionary>
        <local:BilledMsisdnControl x:Key="BilledMsisdnControl"/>
        <local:ImeiControl x:Key="ImeiControl"/>
        <local:StyleConverter x:Key="StyleConverter"/>
    </ResourceDictionary>
</UserControl.Resources>

它们是由我创建的用户控件。

所以我的目标是根据绑定视图模型类型 select 用户控制(这部分有效),然后将其用作 ContentTemplate(这不起作用)。我在图表节点中得到 ImeiControl 或 BilledMsisdnControl 的对象命名空间和名称。

我该如何解决这个问题?

根据 documentation 你应该使用样式选择器

public class NodeStyleSelector : StyleSelector 
{ 
    public Style BilledMsisdnStyle { get; set; } 
    public Style BilledImeiStyle { get; set; } 
 
    public override Style SelectStyle(object item, DependencyObject container) 
    { 
        if (item is BilledMsisdnViewModel) 
            return BilledMsisdnStyle; 
        else if (item is BilledImeiViewModel) 
            return BilledImeiStyle; 
        else return base.SelectStyle(item, container); 
    } 
}

使用 ContentTemplate 定义样式。在 ContentTemplate 内添加您的用户控件。

<Style x:Key="BilledMsisdnStyle" TargetType="telerik:RadDiagramShape">
    <Setter Property="Position" Value="{Binding Position, Mode=TwoWay}" />
    <Setter Property="Content" Value="{Binding}" />
    <Setter Property="Geometry" Value="{telerik:CommonShape ShapeType=RectangleShape}" />
    <Setter Property="ContentTemplate" >
        <Setter.Value> 
            <DataTemplate> 
                <local:BilledMsisdnControl/> 
            </DataTemplate> 
        </Setter.Value> 
    </Setter>
</Style>


<Style x:Key="BilledImeiStyle" TargetType="telerik:RadDiagramShape">
    <Setter Property="Position" Value="{Binding Position, Mode=TwoWay}" />
    <Setter Property="Content" Value="{Binding}" />
    <Setter Property="Geometry" Value="{telerik:CommonShape ShapeType=RectangleShape}" />
    <Setter Property="ContentTemplate" >
        <Setter.Value> 
            <DataTemplate> 
                <local:ImeiControl/> 
            </DataTemplate> 
        </Setter.Value> 
    </Setter>
</Style>

添加形状样式选择器

<styleselectors:NodeStyleSelector x:Key="CustomShapeStyleSelector" 
                BilledMsisdnStyle="{StaticResource BilledMsisdnStyle}" 
                BilledImeiStyle="{StaticResource BilledImeiStyle}" /> 

为您的 RadDiagram 使用 ShapeStyleSelector

<telerik:RadDiagram x:Name="Diagram"
                        ShapeStyleSelector="{StaticResource CustomShapeStyleSelecto}"
                        GraphSource="{Binding GraphSource}"/>