简体   繁体   中英

How to debug a uwp custom control at design time

With the 15.8 version of Visual Studio, we lost (again) the XAML Designer in a UWP project that uses some custom controls.

When we open a XAML file in design mode, it shows a big yellow border around some of our custom controls.

在此处输入图片说明

I know this yellow border comes because the custom control throws an exception at design time. But I have no details about this exception. There are no errors in the Visual Studio errors list. No error message anywhere...

I would like to debug my custom controls so that I can fix the problem. I searched and I can't find a way to debug the UWP XAML Design mode...

Could you please tell me how can I debug or have more details about what error happens in design mode ?

Edit : I finally got some errors in the VS errors list : 在此处输入图片说明 在此处输入图片说明

(Sorry, my Visual Studio is in french). If I recompile my solution, the errors just disappears. But the designer is still unusable.

Edit 2 : Here is the code for CommandViewModelCollection and CommandViewModel. These classes are in a Universal Windows Library. My UWP application references this libray :

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));
}

You might have some code being executed in the ctor of that custom control which might not be fully supported under the VS XAML designer. You can disable this code from running in design time by using an if statement with https://docs.microsoft.com/en-us/uwp/api/windows.applicationmodel.designmode.designmodeenabled#Windows_ApplicationModel_DesignMode_DesignModeEnabled

MS also introduced another property for this: https://docs.microsoft.com/en-us/uwp/api/windows.applicationmodel.designmode.designmode2enabled#Windows_ApplicationModel_DesignMode_DesignMode2Enabled

I don't think there is a way to see what exception was thrown inside the XAML designer.

Update: Based on the code you've added, here is my suggestion:

  • Your CommandViewModelCollection Should inherit from DependencyObject so you can start using DependencyProperty in it.

  • In that class, define a new DependencyProperty like this:

    public static readonly DependencyProperty CommandsCollectionProperty = DependencyProperty.Register("CommandsCollection", typeof(ObservableCollection<CommandViewModel>), typeof(CommandViewModelCollection), new PropertyMetadata(new ObservableCollection<CommandViewModel>(), OnCommandsCollectionPropertyChanged));

  • OnCommandsCollectionPropertyChanged is very important because you will use it to listen to changes to the collection and attach an event handler for collection changes like:

     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 }

This should allow you to initialize the collection from XAML directly.

For anyone stumbling upon this answer after me, you can debug into the XAML Designer by attaching a second instance of Visual Studio to the one displaying the custom control you're attempting to debug.

Full instructions can be found here: https://docs.microsoft.com/en-us/visualstudio/debugger/walkthrough-debugging-at-design-time?view=vs-2019

I have tried this and was successfully able to debug a control I'd been developing which had curious behaviour at design time.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM