当我调整窗口大小时,带有数据选择器的 UWP Treeview 在 App.g.cs 中生成错误 [英] UWP Treeview with Data selector generating an error in App.g.cs when I resize the window

查看:33
本文介绍了当我调整窗口大小时,带有数据选择器的 UWP Treeview 在 App.g.cs 中生成错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

团队,这是非常奇怪的事情,我不明白如何调试它.我有一个树视图.在树视图中,我有两种类型:顾客访问

Team, this is something very strange and I do not understand how to debug it. I have a tree view. Within the tree view I have 2 types: Customer Visit

所有根元素都是客户所有子元素都是访问

ALL root elements are Customers ALL child elements are Visits

我做了一些选择器来显示关卡的正确图标:

I've done some selectors to show the correct icons for the level:

现在,当我打开叶子时,如果列表没有超过树视图的末尾,它会起作用:

Now when I open the leafs IF the list does NOT exceed the end of the tree view it works:

但是如果我打开一个超出窗口一侧的叶子:

But if I open a leaf that EXCEEDS the window side:

我收到此错误:

发件人:应用程序例外:{"指定的演员表无效."}

Sender: the App Exception: {"Specified cast is not valid."}

留言:

"System.InvalidCastException: Unable to cast object of type 'TitoDoc2020.Models.MTreeViewVisit' to type 'TitoDoc2020.Models.MTreeViewPaz'.
   at TitoDoc2020.Views.TitoDocPage.TitoDocPage_obj107_Bindings.SetDataRoot(Object newDataRoot)
   at TitoDoc2020.Views.TitoDocPage.TitoDocPage_obj107_Bindings.ProcessBindings(Object item, Int32 itemIndex, Int32 phase, Int32& nextPhase)"

但我不是在铸造那个!我真的不明白它会在哪里发生.

BUT I'm NOT casting that! I really do not understand where it could happen.

完整项目在此处可见.

推荐答案

根据错误信息的描述,出现这种情况的原因与绑定的类型转换有关,与是否脱离无关窗户.

According to the description of the error message, the reason for this is on the type conversion of the binding and has nothing to do with whether it is out of the window.

请检查您的绑定数据,看看您是否错误地将 MTreeViewVisit 绑定到 MTreeViewPaz.

Please check your binding data to see if you have incorrectly bound MTreeViewVisit to MTreeViewPaz.

更新

初步猜测可能是窗口的调整导致了可见区域的变化,进而导致了一些TreeView入口加载问题.

The initial speculation may be that the adjustment of the window caused the change in the visible area, which in turn caused some TreeView entry loading problems.

我注意到在项目中你会在加载数据时创建一个TitoDocContext,这是不推荐的.

I noticed that in the project you will create a TitoDocContext whenever it comes to loading data, which is not recommended.

你应该只创建一个TitoDocContext,并在需要的地方传递引用,而不是使用using语句来释放上下文.因为频繁创建DbContext会带来巨大的资源开销,这也可能和你的TreeView入口加载异常有关.事实上,我创建了一个包含 1000 个条目的 List,在去掉 SqlServer 后,它运行良好.

You should only create a TitoDocContext, and pass the reference where it is needed, not use the using statement to release the Context. Because the frequent creation of DbContext will bring huge resource overhead, this may also be related to your TreeView entry loading exception. In fact, I created a List with 1000 entries and after getting rid of SqlServer, it worked well.

更新

我转载了你的问题.从实际问题来看,应该是TreeView内部的entry重用所致.为了减少系统资源的开销,TreeView(包括ListViewGridView)会复用之前渲染的模板.因为你使用了ItemTemplateSelector,实际数据类型和复用的模板不一致,导致报错.

I reproduced your question. From the point of view of the actual problem, it should be due to the reuse of entries within the TreeView. In order to reduce the overhead of system resources, TreeView (including ListView and GridView) will reuse previously rendered templates. Because you used ItemTemplateSelector, the actual data type and the reused template are inconsistent, causing an error.

我的建议是创建一个 UserControl 来替换 ItemTemplateSelector.

My suggestion is to create a UserControl to replace ItemTemplateSelector.

1.提取访问集合并创建基类

public class MTreeViewBase
{
    public ObservableCollection<MTreeViewVisit> Visits { get; } = new ObservableCollection<MTreeViewVisit>();
}

public class MTreeViewVisit : MTreeViewBase { }
public class MTreeViewPaz : MTreeViewBase { }

2.创建用户控件

TestControl.xaml

<UserControl.Resources>
    <DataTemplate x:Name="PAZTemplate" x:DataType="model:MTreeViewPaz">
        <StackPanel Orientation="Horizontal">
            <FontIcon
                    Margin="{StaticResource XXSmallTopRightBottomMargin}"
                    FontFamily="{StaticResource SymbolThemeFontFamily}"
                    Glyph="&#xE77B;" />
            <TextBlock
                    Margin="{StaticResource XXSmallTopRightBottomMargin}"
                    VerticalAlignment="Center"
                    Text="{x:Bind Name}" />
        </StackPanel>
    </DataTemplate>
    <DataTemplate x:Name="VisitTemplate" x:DataType="model:MTreeViewVisit">
        <StackPanel Orientation="Horizontal">
            <FontIcon
                    Margin="{StaticResource XXSmallTopRightBottomMargin}"
                    FontFamily="{StaticResource SymbolThemeFontFamily}"
                    Foreground="{x:Bind ImageColor}"
                    Glyph="{x:Bind ImageSrc}" />
            <TextBlock
                    Margin="{StaticResource XXSmallTopRightBottomMargin}"
                    VerticalAlignment="Center"
                    Text="{x:Bind VisitDescr}" />
        </StackPanel>
    </DataTemplate>
</UserControl.Resources>
<Grid>
    <ContentControl x:Name="MainContent"/>
</Grid>

3.为内部转换创建依赖属性

TestControl.xaml.cs

public MTreeViewBase Data
{
    get { return (MTreeViewBase)GetValue(DataProperty); }
    set { SetValue(DataProperty, value); }
}

// Using a DependencyProperty as the backing store for Data.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty DataProperty =
    DependencyProperty.Register("Data", typeof(MTreeViewBase), typeof(TestControl), new PropertyMetadata(null,new PropertyChangedCallback(Data_Changed)));

private static void Data_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    if (e.NewValue != null)
    {
        var instance = d as TestControl;
        if(e.NewValue is MTreeViewPaz)
        {
            instance.MainContent.ContentTemplate = instance.PAZTemplate;
        }
        else
        {
            instance.MainContent.ContentTemplate = instance.VisitTemplate;
        }
    }
}

4.修改你的 TreeView 和 ItemTemplate

<DataTemplate x:Key="BaseTemplate" x:DataType="model:MTreeViewBase">
    <winui:TreeViewItem
        IsExpanded="False"
        ItemsSource="{x:Bind Visits}">
        <controls1:TestControl Data="{Binding}"/>
    </winui:TreeViewItem>
</DataTemplate>

<winui:TreeView
    ...
    ItemTemplate="{StaticResource BaseTemplate}"
    ... />

这样可以保证两种类型有相同的入口,并且在内部进行转换,可以有效的解决这个问题.

This can ensure that the two types have the same entrance, and the conversion is done internally, which can effectively solve this problem.

谢谢.

这篇关于当我调整窗口大小时,带有数据选择器的 UWP Treeview 在 App.g.cs 中生成错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆