WPF中绑定时出现的Markup.IStyle.Connector.Connect错误

8
好的时间。我在WPF中有一个数据绑定问题。如果我使用绑定:
<TextBlock Text="{Binding Key}" TextTrimming="CharacterEllipsis" 
MaxWidth="{Binding ActualWidth, RelativeSource={RelativeSource 
AncestorType={x:Type Expander}}, Converter={StaticResource string_cutter_width}}"/>

在下面的代码中,一些计算机会出现Markup.IStyle.Connector.Connect错误,我不明白为什么会这样。如果你遇到了这种情况或有一些想法,请分享。
            <DataGridTemplateColumn Header="{x:Static res:Resources.status_col_header}" Width="1*">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <DataTemplate.Resources>
                            <local:Localizer2 x:Key="Localizer2" />
                        </DataTemplate.Resources>
                        <Expander Header="{Binding status.Text, Converter={StaticResource Localizer2}}" MouseEnter="Expander_MouseEnter" Tag="{Binding}">
                            <TreeView x:Name="GTree" ItemsSource="{Binding status.files}" ScrollViewer.HorizontalScrollBarVisibility="Hidden">
                                <TreeView.ItemTemplate>
                                    <DataTemplate>
                                        <StackPanel Orientation="Horizontal" ClipToBounds="False" IsHitTestVisible="true" Margin="1">
                                            <StackPanel Orientation="Vertical">
                                                <StackPanel.Resources>
                                                    <local:string_cutter_width x:Key="string_cutter_width" />
                                                </StackPanel.Resources>
                                                <TextBlock Text="{Binding Key}" TextTrimming="CharacterEllipsis" MaxWidth="{Binding ActualWidth, RelativeSource={RelativeSource AncestorType={x:Type Expander}}, Converter={StaticResource string_cutter_width}}"/>
                                                <TextBlock Text="{Binding Value}" TextTrimming="CharacterEllipsis" MaxWidth="{Binding ActualWidth, RelativeSource={RelativeSource AncestorType={x:Type Expander}}, Converter={StaticResource string_cutter_width}}"/>
                                                <!--<TextBlock Text="{Binding Key}" TextTrimming="CharacterEllipsis"/>
                                                <TextBlock Text="{Binding Value}" TextTrimming="CharacterEllipsis"/>-->
                                            </StackPanel >
                                            <StackPanel Orientation="Vertical" HorizontalAlignment="Right" VerticalAlignment="Center">
                                                <StackPanel.Resources>
                                                    <local:del_label_converter x:Key="del_label_converter" />
                                                </StackPanel.Resources>
                                                <!--<Image Source="Resources\delete_16.png" Stretch="UniformToFill" PreviewMouseUp="Image_MouseUp" Width="16" Height="16" Tag="{Binding}" Visibility="{Binding IsEnabled, ElementName=start_btn, Converter={StaticResource del_label_converter} }"/>-->
                                                <Image Source="Resources\delete_16.png" Stretch="UniformToFill" PreviewMouseUp="Image_MouseUp" Width="16" Height="16" Tag="{Binding}"/>
                                            </StackPanel>
                                        </StackPanel>
                                    </DataTemplate>
                                </TreeView.ItemTemplate>
                            </TreeView>
                        </Expander>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>

        <DataGrid.ContextMenu>
            <ContextMenu>
                <MenuItem Header="Проверка подключения CamDrive" Click="MenuItem_Click" IsEnabled="{Binding Path=camdrive_can_be_chk_manually}"/>
                <!--<MenuItem Header="Перезагрузка камеры" Click="RebootCamera_Click"/>-->
            </ContextMenu>
        </DataGrid.ContextMenu>
    </DataGrid>

调用栈:

в Camdrive.UpgradeTools.MainWindow.System.Windows.Markup.IStyleConnector.Connect(Int32 connectionId, Object target) в c:\Develop\Camdrive.Utils\Camdrive.UpgradeTools\Camdrive.UpgradeTools\MainWindow.xaml:строка 75
в System.Windows.FrameworkTemplate.LoadTemplateXaml(XamlReader templateReader, XamlObjectWriter currentWriter)
в System.Windows.FrameworkTemplate.LoadTemplateXaml(XamlObjectWriter objectWriter)
в System.Windows.FrameworkTemplate.LoadOptimizedTemplateContent(DependencyObject container, IComponentConnector componentConnector, IStyleConnector styleConnector, List`1 affectedChildren, UncommonField`1 templatedNonFeChildrenField)
в System.Windows.FrameworkTemplate.LoadContent(DependencyObject container, List`1 affectedChildren)
в System.Windows.StyleHelper.ApplyTemplateContent(UncommonField`1 dataField, DependencyObject container, FrameworkElementFactory templateRoot, Int32 lastChildIndex, HybridDictionary childIndexFromChildID, FrameworkTemplate frameworkTemplate)
в System.Windows.FrameworkTemplate.ApplyTemplateContent(UncommonField`1 templateDataField, FrameworkElement container)
в System.Windows.FrameworkElement.ApplyTemplate()
в System.Windows.FrameworkElement.MeasureCore(Size availableSize)
в System.Windows.UIElement.Measure(Size availableSize)
в MS.Internal.Helper.MeasureElementWithSingleChild(UIElement element, Size constraint)
в System.Windows.Controls.ContentPresenter.MeasureOverride(Size constraint)
в System.Windows.FrameworkElement.MeasureCore(Size availableSize)
в System.Windows.UIElement.Measure(Size availableSize)
в System.Windows.Controls.Border.MeasureOverride(Size constraint)
в System.Windows.FrameworkElement.MeasureCore(Size availableSize)
в System.Windows.UIElement.Measure(Size availableSize)
в System.Windows.Controls.Control.MeasureOverride(Size constraint)
в System.Windows.Controls.DataGridCell.MeasureOverride(Size constraint)
в System.Windows.FrameworkElement.MeasureCore(Size availableSize)
в System.Windows.UIElement.Measure(Size availableSize)
в System.Windows.Controls.DataGridCellsPanel.MeasureChild(UIElement child, Size constraint)
в System.Windows.Controls.DataGridCellsPanel.GenerateChild(IItemContainerGenerator generator, Size constraint, DataGridColumn column, Int32& childIndex, Size& childSize)
в System.Windows.Controls.DataGridCellsPanel.GenerateChildren(IItemContainerGenerator generator, Int32 startIndex, Int32 endIndex, Size constraint)
в System.Windows.Controls.DataGridCellsPanel.GenerateAndMeasureChildrenForRealizedColumns(Size constraint)
в System.Windows.Controls.DataGridCellsPanel.MeasureOverride(Size constraint)
в System.Windows.FrameworkElement.MeasureCore(Size availableSize)
в System.Windows.UIElement.Measure(Size availableSize)
в MS.Internal.Helper.MeasureElementWithSingleChild(UIElement element, Size constraint)
в System.Windows.Controls.ItemsPresenter.MeasureOverride(Size constraint)
в System.Windows.FrameworkElement.MeasureCore(Size availableSize)
в System.Windows.UIElement.Measure(Size availableSize)
в System.Windows.Controls.Control.MeasureOverride(Size constraint)
в System.Windows.Controls.Primitives.DataGridCellsPresenter.MeasureOverride(Size availableSize)
в System.Windows.FrameworkElement.MeasureCore(Size availableSize)
в System.Windows.UIElement.Measure(Size availableSize)
в System.Windows.Controls.Grid.MeasureCell(Int32 cell, Boolean forceInfinityV)
в System.Windows.Controls.Grid.MeasureCellsGroup(Int32 cellsHead, Size referenceSize, Boolean ignoreDesiredSizeU, Boolean forceInfinityV)
в System.Windows.Controls.Grid.MeasureOverride(Size constraint)
в System.Windows.FrameworkElement.MeasureCore(Size availableSize)
в System.Windows.UIElement.Measure(Size availableSize)
в System.Windows.Controls.Border.MeasureOverride(Size constraint)
в System.Windows.FrameworkElement.MeasureCore(Size availableSize)
в System.Windows.UIElement.Measure(Size availableSize)
в System.Windows.Controls.Control.MeasureOverride(Size constraint)
в System.Windows.FrameworkElement.MeasureCore(Size availableSize)
в System.Windows.UIElement.Measure(Size availableSize)
в System.Windows.Controls.VirtualizingStackPanel.MeasureOverride(Size constraint)
в System.Windows.Controls.Primitives.DataGridRowsPresenter.MeasureOverride(Size constraint)
в System.Windows.FrameworkElement.MeasureCore(Size availableSize)
в System.Windows.UIElement.Measure(Size availableSize)
в System.Windows.ContextLayoutManager.UpdateLayout()
в System.Windows.ContextLayoutManager.UpdateLayoutCallback(Object arg)
в System.Windows.Media.MediaContext.InvokeOnRenderCallback.DoWork()
в System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks()
в System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object  resizedCompositionTarget)
в System.Windows.Media.MediaContext.RenderMessageHandler(Object resizedCompositionTarget)
в System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
в MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
в System.Windows.Threading.DispatcherOperation.InvokeImpl()
в System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
в System.Threading.ExecutionContext.runTryCode(Object userData)
в System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
в System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
в System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
в System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
в System.Windows.Threading.DispatcherOperation.Invoke()
в System.Windows.Threading.Dispatcher.ProcessQueue()
в System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr  wParam, IntPtr lParam, Boolean& handled)
в MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam,  Boolean& handled)
в MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
в System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object  args, Int32 numArgs)
в MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
в System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
в MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
в MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
в System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
в System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
в System.Windows.Application.RunDispatcher(Object ignore)
в System.Windows.Application.RunInternal(Window window)
в System.Windows.Application.Run(Window window)
в System.Windows.Application.Run()
в Camdrive.UpgradeTools.App.Main() в C:\Develop\Camdrive.Utils\Camdrive.UpgradeTools\Camdrive.UpgradeTools\obj\x86\Debug\App.g.cs:строка 0
в System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
в System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
в Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
в System.Threading.ThreadHelper.ThreadStart_Context(Object state)
в System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
в System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
в System.Threading.ThreadHelper.ThreadStart()
1个回答

13

很可能是由于嵌套模板:

单元格模板 -> DataTemplate -> ... -> 树形视图(TreeView) -> 树形视图(TreeView).ItemTemplate -> DataTemplate

引用这里的内容:

这个错误需要在一个模板中再使用另一个模板。理解这个问题的一个好方法是“模板就像括号,引用括号”,XAML模板不会立即创建,而是保存并稍后运行。因此,这个错误是:我们在嵌套的括号中存在问题。

在示例中:

<Grid>
    <ListBox ItemsSource="{StaticResource Data}" >
        <ListBox.ItemTemplate>
            <DataTemplate>
                <ListBox ItemsSource="{Binding .}">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding .}" Width="30"
                                     Loaded="TextBlock_Loaded"
                                     Style="{StaticResource TextBlockStyle}" />
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

应用外部模板时,内部模板仍然被“引用”。但是我们仍然对所有XAML调用IStyleConnector.Connect()(即使我们遇到了内部括号/引号),因此没有TextBlock实例,导致程序崩溃。

由于优化的模板共享,因此会出现奇怪的情况。例如,如果您删除以下内容:

Style="{StaticResource TextBlockStyle}"

由于模板优化器中的TextBlock变得可以共享,因此该错误消失了。

解决方法:

最好的解决方法是将内部模板移动到资源中。

尝试将TreeView.ItemTemplate移到资源中。


1
有没有特定版本的.NET会出现这个问题?为什么有些机器会出现这个问题,而其他机器则不会?你的解决方法和建议非常有效! - Mike G
@Mike G:机器上的框架版本是什么?这个错误已经从.NET 3.5移动到了.NET 4.0版本,完全相同的代码在3.5下没有问题。可能在4.5版本中已经修复了,正如微软所承诺的那样。无论如何,我认为应该避免嵌套模板并通过资源使用。 - Anatoliy Nikolaev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接