You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用SfNavigationDrawer时如何阻止WPF DataTemplateSelector触发

解决SfNavigationDrawer中阻止DataTemplateSelector触发并打开子菜单的问题

核心问题原因

返回null会导致SfNavigationDrawer尝试复用已加载的视觉元素,从而触发“必须先断开子元素与当前父视觉的连接”的错误——控件无法正确处理无模板返回的情况。

正确实现步骤

  1. 给目标导航项添加标记
    在需要打开子菜单的NavigationItem上通过Tag属性标记(比如设为"SubMenu"),用于模板选择器识别。

  2. 修改DataTemplateSelector逻辑
    不要返回null,而是返回SfNavigationDrawer的默认导航项模板(或者定义一个空的基础模板),让控件正常渲染基础导航项,同时保留子菜单展开的原生行为。

  3. 确保子菜单配置正确
    给标记的NavigationItem添加子项集合,确保SfNavigationDrawer能识别这是一个可展开的父菜单。

修改后的代码示例

public class MyTemplateSelector : DataTemplateSelector
{
    public DataTemplate dt1 { get; set; }
    public DataTemplate dt2 { get; set; }
    // 定义默认模板(可在XAML中绑定SfNavigationDrawer的默认项模板,或创建基础模板)
    public DataTemplate DefaultNavigationItemTemplate { get; set; }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        if (item is NavigationItem navigationItem && navigationItem.Header != null)
        {
            // 判断是否为需要打开子菜单的项
            if (navigationItem.Tag?.ToString() == "SubMenu")
            {
                // 返回默认模板,保留子菜单展开行为
                return DefaultNavigationItemTemplate;
            }

            switch (navigationItem.Header.ToString())
            {
                case "item1":
                    return dt1;
                case "item2":
                    return dt2;
                default:
                    return DefaultNavigationItemTemplate;
            }
        }
        return DefaultNavigationItemTemplate;
    }
}

XAML配置示例

<!-- 定义默认导航项模板 -->
<DataTemplate x:Key="DefaultNavItemTemplate">
    <syncfusion:NavigationItemView Content="{Binding Header}" 
                                   ItemsSource="{Binding Items}"/>
</DataTemplate>

<!-- 配置模板选择器 -->
<local:MyTemplateSelector x:Key="MyTemplateSelector"
                          dt1="{StaticResource dt1}"
                          dt2="{StaticResource dt2}"
                          DefaultNavigationItemTemplate="{StaticResource DefaultNavItemTemplate}"/>

<!-- SfNavigationDrawer绑定模板选择器 -->
<syncfusion:SfNavigationDrawer x:Name="navigationDrawer"
                               ItemTemplateSelector="{StaticResource MyTemplateSelector}">
    <!-- 导航项集合,给需要子菜单的项加Tag -->
    <syncfusion:SfNavigationDrawer.Items>
        <syncfusion:NavigationItem Header="item1"/>
        <syncfusion:NavigationItem Header="item2"/>
        <syncfusion:NavigationItem Header="子菜单父项" Tag="SubMenu">
            <syncfusion:NavigationItem.Items>
                <syncfusion:NavigationItem Header="子项1"/>
                <syncfusion:NavigationItem Header="子项2"/>
            </syncfusion:NavigationItem.Items>
        </syncfusion:NavigationItem>
    </syncfusion:SfNavigationDrawer.Items>
</syncfusion:SfNavigationDrawer>

额外注意事项

  • 确保DefaultNavigationItemTemplate包含ItemsSource绑定,这样SfNavigationDrawer才能识别并展开子菜单。
  • 不要依赖返回null来跳过模板选择,控件的模板选择逻辑要求必须返回有效的DataTemplate实例。

内容的提问来源于stack exchange,提问作者Павел Закриев

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 13:28:22