创建一个从代码继承NavigationView的控件在加载时会抛出异常。

huangapple go评论78阅读模式
英文:

Creating a control that inherits NavigationView from code throws an exception when it is loaded

问题

<!--MainWindow.xaml-->

<Window x:Class="TestApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" />
// MainWindow.xaml.cs

namespace TestApp
{
    internal sealed partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }
}
// App.xaml.cs

namespace TestApp
{
    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();
        }

        protected override void OnLaunched(LaunchActivatedEventArgs args)
        {
            var mainWindow = new MainWindow();
            mainWindow.Content = new SubControl();
            mainWindow.Activate();
        }
    }
}
// SubControl.cs

namespace TestApp.Controls
{
    internal class SubControl : NavigationView
    {
    }
}

The above code causes exception when SubControl is loaded.

e.Exception: {"No installed components were detected. (0x800F1000)"}, System.Exception {System.Runtime.InteropServices.COMException}

e.Message: "Cannot apply a Style with TargetType 'Microsoft.UI.Xaml.Controls.NavigationView' to an object of type 'Microsoft.UI.Xaml.Controls.ContentControl'."

If SubControl is created from xaml or inherits Button, TextBox, CheckBox, etc., it will function normally.

What I'm trying to do is create a custom control that inherits NavigationView. In order to implement the part that I want to customize, I think it would be better to do subclassing than applying Behavior.

An exception is thrown when applying breakpoints to "mainWindow.Content = new SubControl();".

If you do not apply breakpoints, there are no exceptions, but the control is not displayed.


<details>
<summary>英文:</summary>

<!--MainWindow.xaml-->

<Window x:Class="TestApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" />

// MainWindow.xaml.cs

namespace TestApp
{
internal sealed partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
}

// App.xaml.cs

namespace TestApp
{
public partial class App : Application
{
public App()
{
InitializeComponent();
}

    protected override void OnLaunched(LaunchActivatedEventArgs args)
    {
        var mainWindow = new MainWindow();
        mainWindow.Content = new SubControl();
        mainWindow.Activate();
    }
}

}

// SubControl.cs

namespace TestApp.Controls
{
internal class SubControl : NavigationView
{
}
}

The above code causes exception when SubControl is loaded.

e.Exception: {&quot;No installed components were detected. (0x800F1000)&quot;}, System.Exception {System.Runtime.InteropServices.COMException}

e.Message: &quot;Cannot apply a Style with TargetType &#39;Microsoft.UI.Xaml.Controls.NavigationView&#39; to an object of type &#39;Microsoft.UI.Xaml.Controls.ContentControl&#39;.&quot;

If SubControl is created from xaml or inherits Button, TextBox, CheckBox, etc., it will function normally.

What I&#39;m trying to do is create a custom control that inherits NavigationView. In order to implement the part that I want to customize, I think it would be better to do subclassing than applying Behavior.

An exception is thrown when applying breakpoints to &quot;mainWindow.Content = new SubControl();&quot;.

If you do not apply breakpoints, there are no exceptions, but the control is not displayed.

</details>


# 答案1
**得分**: 1

你可以在其他没有*Default____Style*(例如*DefaultButtonStyle*)的控件上得到相同的行为。

我现在唯一想到的解决方法是从[generic.xaml](https://stackoverflow.com/a/75318162/2411960)中引入样式,并将``TargetType``更改为*SubControl*。

```xaml
&lt;Style TargetType=&quot;local:SubControl&quot;&gt;
    &lt;Setter Property=&quot;PaneToggleButtonStyle&quot; Value=&quot;{StaticResource PaneToggleButtonStyle}&quot; /&gt;
    &lt;Setter Property=&quot;IsTabStop&quot; Value=&quot;False&quot; /&gt;
    &lt;Setter Property=&quot;CompactPaneLength&quot; Value=&quot;{ThemeResource NavigationViewCompactPaneLength}&quot; /&gt;
    &lt;Setter Property=&quot;CornerRadius&quot; Value=&quot;{ThemeResource OverlayCornerRadius}&quot; /&gt;
    &lt;Setter Property=&quot;Template&quot;&gt;
        &lt;Setter.Value&gt;
            &lt;ControlTemplate TargetType=&quot;local:SubControl&quot;&gt;
:
:
:
&lt;/Style&gt;
英文:

You get the same behavior with another controls that doesn't have a Default____Style (e.g. DefaultButtonStyle).

The only workaround that I can come up for the moment is to bring the style from the generic.xaml and change the TargetType to SubControl.

&lt;Style TargetType=&quot;local:SubControl&quot;&gt;
    &lt;Setter Property=&quot;PaneToggleButtonStyle&quot; Value=&quot;{StaticResource PaneToggleButtonStyle}&quot; /&gt;
    &lt;Setter Property=&quot;IsTabStop&quot; Value=&quot;False&quot; /&gt;
    &lt;Setter Property=&quot;CompactPaneLength&quot; Value=&quot;{ThemeResource NavigationViewCompactPaneLength}&quot; /&gt;
    &lt;Setter Property=&quot;CornerRadius&quot; Value=&quot;{ThemeResource OverlayCornerRadius}&quot; /&gt;
    &lt;Setter Property=&quot;Template&quot;&gt;
        &lt;Setter.Value&gt;
            &lt;ControlTemplate TargetType=&quot;local:SubControl&quot;&gt;
:
:
:
&lt;/Style&gt;

答案2

得分: 1

@AndrewKeepCoding 正在尝试解决 Control.DefaultStyleKey 问题。在最简单的情况下,您可以使用 NavigationView 样式。只需添加一个新的自定义控件并替换以下代码。

// Copyright (c) Microsoft Corporation and Contributors.
// Licensed under the MIT License.

using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Documents;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;

// 要了解有关 WinUI、WinUI 项目结构以及我们的项目模板的更多信息,请参阅:http://aka.ms/winui-project-info.

namespace App2CSharp
{
    public sealed class CustomControl1 : NavigationView
    {
        public CustomControl1()
        {
            this.DefaultStyleKey = typeof(NavigationView);
        }

        protected override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
        }
    }
}

创建一个从代码继承NavigationView的控件在加载时会抛出异常。

英文:

@AndrewKeepCoding was trying to resolve Control.DefaultStyleKey. With the simplest case, you can use the NavigationView style. Just add a new custom control and replace the following code.

// Copyright (c) Microsoft Corporation and Contributors.
// Licensed under the MIT License.

using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Documents;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;

// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.

namespace App2CSharp
{
    public sealed class CustomControl1 : NavigationView
    {
        public CustomControl1()
        {
            this.DefaultStyleKey = typeof(NavigationView);
        }

        protected override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
        }
    }
}

创建一个从代码继承NavigationView的控件在加载时会抛出异常。

huangapple
  • 本文由 发表于 2023年5月21日 11:58:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/76298240.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定