C# 如何在设计时调试uwp自定义控件

C# 如何在设计时调试uwp自定义控件,c#,visual-studio,xaml,uwp,C#,Visual Studio,Xaml,Uwp,在15.8版本的VisualStudio中,我们(再次)在一个使用一些自定义控件的UWP项目中丢失了XAML设计器 当我们在设计模式下打开XAML文件时,它会在一些自定义控件周围显示一个大的黄色边框 我知道这个黄色边框是因为自定义控件在设计时抛出异常。但是我没有关于这个例外的细节。Visual Studio错误列表中没有错误。任何地方都没有错误消息 我想调试我的自定义控件,以便修复该问题。我搜索了,但找不到调试UWP XAML设计模式的方法 您能告诉我如何调试或了解设计模式中发生的错误的更多细

在15.8版本的VisualStudio中,我们(再次)在一个使用一些自定义控件的UWP项目中丢失了XAML设计器

当我们在设计模式下打开XAML文件时,它会在一些自定义控件周围显示一个大的黄色边框

我知道这个黄色边框是因为自定义控件在设计时抛出异常。但是我没有关于这个例外的细节。Visual Studio错误列表中没有错误。任何地方都没有错误消息

我想调试我的自定义控件,以便修复该问题。我搜索了,但找不到调试UWP XAML设计模式的方法

您能告诉我如何调试或了解设计模式中发生的错误的更多细节吗

编辑:我终于在VS错误列表中找到了一些错误:

(对不起,我的Visual Studio是法语的)。如果我重新编译我的解决方案,错误就会消失。但设计师仍然无法使用

编辑2: 以下是CommandViewModelCollection和CommandViewModel的代码。这些类位于通用Windows库中。我的UWP应用程序引用此库:

public class CommandViewModelCollection : ObservableCollection<CommandViewModel>
{
}

public class CommandViewModel : ViewModelBase
{
    public ICommand Command
    {
        get { return _Command; }
        set
        {
            if (_Command != value)
            {
                _Command = value;
                this.OnPropertyChanged(_CommandChangedEventArgs);
            }
        }
    }

    private ICommand _Command;
    private static readonly PropertyChangedEventArgs _CommandChangedEventArgs = new PropertyChangedEventArgs(nameof(Command));

    public ImageSource Icon
    {
        get { return _Icon; }
        set
        {
            if (_Icon != value)
            {
                _Icon = value;
                this.OnPropertyChanged(_IconChangedEventArgs);
            }
        }
    }

    private ImageSource _Icon;
    private static readonly PropertyChangedEventArgs _IconChangedEventArgs = new PropertyChangedEventArgs(nameof(Icon));
}

public abstract class ViewModelBase : INotifyPropertyChanged
{
    protected ViewModelBase()
    {
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(PropertyChangedEventArgs args)
    {
        this.PropertyChanged?.Invoke(this, args);
    }

    public string DisplayName
    {
        get { return _DisplayName; }
        set
        {
            if (_DisplayName != value)
            {
                _DisplayName = value;
                this.OnPropertyChanged(_DisplayNameChangedEventArgs);
            }
        }
    }

    private string _DisplayName;
    private static readonly PropertyChangedEventArgs _DisplayNameChangedEventArgs = new PropertyChangedEventArgs(nameof(DisplayName));
}
public类CommandViewModelCollection:ObservableCollection
{
}
公共类CommandViewModel:ViewModelBase
{
公共ICommand命令
{
获取{return\u命令;}
设置
{
如果(_命令!=值)
{
_命令=值;
此.OnPropertyChanged(_CommandChangedEventArgs);
}
}
}
专用ICommand_命令;
私有静态只读属性changedeventargs _CommandChangedEventArgs=新属性changedeventargs(nameof(Command));
公共图像源图标
{
获取{return\u Icon;}
设置
{
如果(_图标!=值)
{
_图标=值;
此.OnPropertyChanged(\u IconChangedEventArgs);
}
}
}
专用图像源图标;
私有静态只读属性changedeventargs _IconChangedEventArgs=新属性changedeventargs(name of(Icon));
}
公共抽象类ViewModelBase:INotifyPropertyChanged
{
受保护的ViewModelBase()
{
}
公共事件属性更改事件处理程序属性更改;
PropertyChanged上受保护的虚拟无效(PropertyChangedEventArgs args)
{
this.PropertyChanged?.Invoke(this,args);
}
公共字符串显示名
{
获取{return\u DisplayName;}
设置
{
如果(_DisplayName!=值)
{
_显示名称=值;
此.OnPropertyChanged(\u DisplayNameChangedEventArgs);
}
}
}
私有字符串_DisplayName;
私有静态只读属性ChangedEventArgs\u DisplayNameChangedEventArgs=新属性ChangedEventArgs(nameof(DisplayName));
}

您可能在该自定义控件的ctor中执行某些代码,而VS XAML设计器可能不完全支持这些代码。您可以通过使用带有

MS还为此引入了另一个属性:

我认为没有办法查看XAML设计器中抛出了什么异常

更新:根据您添加的代码,我的建议如下:

  • 您的
    CommandViewModelCollection
    应该继承自
    DependencyObject
    ,这样您就可以开始在其中使用
    DependencyProperty

  • 在该类中,定义一个新的
    DependencyProperty
    ,如下所示:

    公共静态只读DependencyProperty CommandsCollectionProperty=DependencyProperty.Register(“CommandsCollection”、typeof(ObservableCollection)、typeof(CommandViewModelCollection)、new PropertyMetadata(new ObservableCollection()、OnCommandsCollectionPropertyChanged))

  • OnCommandsCollectionPropertyChanged
    非常重要,因为您将使用它侦听对集合的更改,并为集合更改附加事件处理程序,例如:

    private static void OnCommandsCollectionPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        //add event handler to monitor the changes to this collection
        var @this = (CommandViewModelCollection)d;
        @this.CommandsCollection.CollectionChanged += @this.OnCommandsCollectionCollectionChanged;
    
        //de-attach from old one
        if (e.OldValue is ObservableCollection<CommandViewModel> oldValue)
            oldValue.CollectionChanged -= @this.OnCommandsCollectionChanged;
    
        //any code here to execute based on collection changes
    }
    
    CommandsCollectionPropertyChanged上的私有静态无效(DependencyObject d,DependencyPropertyChangedEventArgs e)
    {
    //添加事件处理程序以监视对此集合的更改
    var@this=(CommandViewModelCollection)d;
    @this.CommandsCollection.CollectionChanged+=@this.OnCommandsCollectionCollectionChanged;
    //脱离旧的
    如果(例如,OldValue是ObservableCollection OldValue)
    oldValue.CollectionChanged-=@this.onCommand和CollectionChanged;
    //此处要根据集合更改执行的任何代码
    }
    

这应该允许您直接从XAML初始化集合。

对于在我之后遇到此问题的任何人,您可以通过将Visual Studio的第二个实例附加到显示您尝试调试的自定义控件的实例,来调试XAML设计器

完整说明可在此处找到:


我已经尝试过了,并且成功地调试了我一直在开发的一个控件,该控件在设计时具有奇怪的行为。

我已经尝试禁用了一些具有这些属性的代码。但我认为创建控件实例是一个问题。黄色大边框是一个占位符控件。如果我的代码在事件中引发异常,则“重新加载设计器”选项会出现一个红色的大错误。@NicolasSéveno你能发布该DependencyProperty的代码吗?我的意思是
CommandModelCollection
我认为设计师试图初始化该属性可能有问题。谢谢你的回答。我编辑并添加了CommandViewModel和CommandViewModelCollection类的代码。我将CommandViewModel类重新实现为依赖项对象。这解决了90%的设计器错误。谢谢@Rafael!