App.xaml对象引用未设置为对象的实例

3

最近安装Blend 4后,我的App.xaml出现了错误,所有的ViewModel现在都显示“对象引用未设置为对象的实例”的错误。卸载Blend 4后,错误消失了几个小时,但现在又回来了。

我已经检查了从项目开始到现在所做的每一个提交,问题仍然存在,我完全困惑了。这导致我的窗口在设计模式下抛出无法定位资源的错误。

编辑:更新:每隔几次构建应用程序,它就会发生变化,这一次是在更改UserControl上按钮的绑定之后发生的。之前是UserListViewModel和SettingViewModel。现在是SettingsViewModel和MainScreenViewModel。

App.xaml:

<Application x:Class="HelpScoutMetrics.App"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:vm="clr-namespace:HelpScoutMetrics.ViewModel">
<Application.Resources>
    <ResourceDictionary>
        <vm:MainScreenViewModel x:Key="MainScreenViewModel" />
        <vm:SettingsViewModel x:Key="SettingsViewModel" />
        <vm:UserListViewModel x:Key="UserListViewModel" />
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
            <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />
            <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml" />
            <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/Blue.xaml" />
            <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseLight.xaml" />
            <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/FlatButton.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

ViewModels:

public class MainScreenViewModel : ViewModelBase
{
    public MainScreenViewModel()
    {
        QuickStatistics = new QuickStats();
        QuickStatistics.UserQuickStats = new ObservableCollection<UserQuickStat>();
        QuickStatistics.UserQuickStats.Add(new UserQuickStat() { Name = "Test", TotalConversations = 93, TotalReplies = 57 });
        ApplicationData.MainViewModel = this; // Temp for debug of issues
    }

    public static Logger logger = LogManager.GetLogger("MainScreenViewModel");

    public MainWindow Window { get; set; }

    private UserReport m_UserOverall;
    public UserReport UserOverall
    {
        get { return m_UserOverall; }
        set { m_UserOverall = value; RaisePropertyChanged("UserOverall"); }
    }

    private QuickStats m_QuickStatistics;
    public QuickStats QuickStatistics
    {
        get { return m_QuickStatistics; }
        set { m_QuickStatistics = value; RaisePropertyChanged("QuickStatistics"); }
    }

    private DateTime m_SelectedDate;
    public DateTime SelectedDate
    {
        get { return m_SelectedDate; }
        set { m_SelectedDate = value; RaisePropertyChanged("SelectedDate"); }
    }

    private ObservableCollection<DateTime> m_SelectedDates;
    public ObservableCollection<DateTime> SelectedDates
    {
        get { return m_SelectedDates; }
        set { m_SelectedDates = value; RaisePropertyChanged("SelectedDates"); }
    }

    private bool m_EnableLoadQuickStatsButton;
    public bool EnableLoadQuickStatsButton
    {
        get { return m_EnableLoadQuickStatsButton; }
        set { m_EnableLoadQuickStatsButton = value; RaisePropertyChanged("EnableLoadQuickStatsButton"); }
    }

    private bool m_EnableLoadQuickStatsButtonTest = false;
    public bool EnableLoadQuickStatsButtonTest
    {
        get { return m_EnableLoadQuickStatsButtonTest; }
        set { m_EnableLoadQuickStatsButtonTest = value; RaisePropertyChanged("EnableLoadQuickStatsButtonTest"); }
    }

    public void NewUser()
    {
        QuickStatistics.UserQuickStats.Add(new UserQuickStat() { Name = "Test2", TotalConversations = 953, TotalReplies = 577 });
    }

    public void OpenSettings()
    {
        if(Window.SettingsFlyout.IsOpen)
        {
            Window.SettingsFlyout.IsOpen = false;
            logger.Log(LogLevel.Info, "Closed Settings Flyout");
        }
        else
        {
            SettingsViewModel viewModel = Window.SettingsFlyout.DataContext as SettingsViewModel;
            viewModel.MainWindow = Window;
            viewModel.LoadSettings();
            Window.SettingsFlyout.IsOpen = true;
            logger.Log(LogLevel.Info, "Opened Settings Flyout");
        }
    }

    public void OpenUsersList()
    {
        if(Window.UserListFlyout.IsOpen)
        {
            Window.UserListFlyout.IsOpen = false;
            logger.Log(LogLevel.Info, "Closed Users List Flyout");
        }
        else
        {
            UserListViewModel viewModel = Window.UserListFlyout.DataContext as UserListViewModel;
            UserListView userListView = Window.UserListFlyoutView;
            viewModel.UserListView = userListView;
            viewModel.MainWindow = Window;
            viewModel.SetupFreshViewModel();

            Window.UserListFlyout.IsOpen = true;
            logger.Log(LogLevel.Info, "Opened Users List Flyout");

        }
    }

    public void OpenLogWindow()
    {
        int count = ApplicationData.MainLogEntries.LogEvents.Count;
        NLogViewerView window = new NLogViewerView();
        window.Show();
        logger.Log(LogLevel.Info, "Opened Log Window");
        EnableLoadQuickStatsButtonTest = true;
    }

    public void RefreshView()// Temp for debug of issues
    {
        foreach (string name in MiscMethods.GetPropertyNames(this))
        {
            RaisePropertyChanged(name);
        }
    }
}

public class SettingsViewModel : ViewModelBase
{
    public SettingsViewModel()
    {
        SettingsWindowLogic.LoadSettings(this);
    }

    private static Logger logger = LogManager.GetLogger("SettingsViewModel");

    public MainWindow MainWindow { get; set; }

    private string m_APIKey;
    public string APIKey
    {
        get { return m_APIKey; }
        set 
        { 
            m_APIKey = value; TriedToValidateKey = false; 
            KeyValidationButtonText = "Verify Key";
            VerifyButtonBackground = new SolidColorBrush(Color.FromArgb(255, 213, 213, 213));
            ApplicationData.ApplicationSettings.ValidAPIKeyExists = false;
            RaisePropertyChanged("APIKey"); 
        }
    }

    private bool m_SaveAPIKey = true;
    public bool SaveAPIKey
    {
        get { return m_SaveAPIKey; }
        set { m_SaveAPIKey = value; RaisePropertyChanged("SaveAPIKey"); }
    }

    /*====================================================================
     *             Key Validation & Button
     * ==================================================================*/

    private bool m_ValidKey;
    public bool ValidKey
    {
        get { return m_ValidKey; }
        set 
        { 
            m_ValidKey = value;
            if(value)
            {
                KeyValidationButtonText = "Valid!";
                VerifyButtonBackground = new SolidColorBrush(Color.FromArgb(255, 18, 145, 47));
                ApplicationData.ApplicationSettings.ValidAPIKeyExists = true;
            }
            else
            {
                KeyValidationButtonText = "Invalid";
                VerifyButtonBackground = new SolidColorBrush(Color.FromArgb(255, 153, 18, 18));
                ApplicationData.ApplicationSettings.ValidAPIKeyExists = false;
            }
            RaisePropertyChanged("ValidKey"); 
        }
    }

    //Will be true when the eky is in process of verification
    private bool m_CurrentlyVerifyingKey;
    public bool CurrentlyVerifyingKey
    {
        get { return m_CurrentlyVerifyingKey; }
        set 
        {
            if (value)
            {
                KeyValidationButtonText = "Verifying...";
            }
            m_CurrentlyVerifyingKey = value; 
            RaisePropertyChanged("CurrentlyVerifyingKey");
        }
    }

    private bool m_TriedToValidateKey;
    public bool TriedToValidateKey
    {
        get { return m_TriedToValidateKey; }
        set { m_TriedToValidateKey = value; RaisePropertyChanged("TriedToValidateKey"); }
    }

    private string m_KeyValidationButtonText = "Verify Key";
    public string KeyValidationButtonText
    {
        get { return m_KeyValidationButtonText; }
        set { m_KeyValidationButtonText = value; RaisePropertyChanged("KeyValidationButtonText"); }
    }

    private Brush m_VerifyButtonBackground = new SolidColorBrush(Color.FromArgb(255, 213, 213, 213));
    public Brush VerifyButtonBackground
    {
        get { return m_VerifyButtonBackground; }
        set { m_VerifyButtonBackground = value; RaisePropertyChanged("VerifyButtonBackground"); }
    }

    public async void VerifyAPIKey()
    {
        //Task<Paged<Mailbox>> testPull = new Task<Paged<Mailbox>>(() => client.ListMailboxes());
        Task<bool> results = new Task<bool>(() => SettingsWindowLogic.VerifyAPIKey(APIKey));
        CurrentlyVerifyingKey = true;

        results.Start();

        CurrentlyVerifyingKey = false;

        if (await results)
        {
            ValidKey = true;
        }
        else
        {
            ValidKey = false;
        }
        TriedToValidateKey = true;
    }



    public void SaveSettings()
    {
        SettingsWindowLogic.SaveSettings(this);
        logger.Log(LogLevel.Debug, "Saved Settings");
        CloseFlyout();
    }

    public void LoadSettings()
    {
        SettingsWindowLogic.LoadSettings(this);
    }
    public void ResetSettings()
    {
        APIKey = string.Empty;
        SaveAPIKey = false;
        ApplicationData.ApplicationSettings.ValidAPIKeyExists = false;
        logger.Log(LogLevel.Debug, "Reset Settings");
    }

    public void CloseFlyout()
    {
        MainWindow.SettingsFlyout.IsOpen = false;
        logger.Log(LogLevel.Info, "Closed Settings Flyout");
    }
}

public class UserListViewModel : ViewModelBase
{
    public UserListViewModel()
    {
       // LoadUserList();
    }

    public static Logger logger = LogManager.GetLogger("UserListViewModel");

    public MainWindow MainWindow { get; set; }
    public UserListView UserListView { get; set; }

    private UserList m_UserList;
    public UserList UsersList
    {
        get { return m_UserList; }
        set { m_UserList = value; RaisePropertyChanged("UsersList"); }
    }

    private List<string> m_TestItems;
    public List<string> TestItems
    {
        get { return m_TestItems; }
        set { m_TestItems = value; RaisePropertyChanged("TestItems"); }
    }

    private string m_NewUserName;
    public string NewUserName
    {
        get { return m_NewUserName; }
        set { m_NewUserName = value; RaisePropertyChanged("NewUserName"); }
    }

    private string m_HelpScoutUserListStatus = "Attempting To Load HelpScout Users...";
    public string HelpScoutUserListStatus
    {
        get { return m_HelpScoutUserListStatus; }
        set { m_HelpScoutUserListStatus = value; RaisePropertyChanged("HelpScoutUserListStatus"); }
    }

    private Brush m_HelpScoutUserListStatusColor = new SolidColorBrush(Color.FromArgb(255, 187, 95, 32));
    public Brush HelpScoutUserListStatusColor
    {
        get { return m_HelpScoutUserListStatusColor; }
        set { m_HelpScoutUserListStatusColor = value; RaisePropertyChanged("HelpScoutUserListStatusColor"); }
    }

    private bool m_HelpScoutUserListLoaded;
    public bool HelpScoutUserListLoaded
    {
        get { return m_HelpScoutUserListLoaded; }
        set 
        { 
            if(value)
            {
                HelpScoutUserListStatus = UserListWindowLogic.HelpScutUseListStringStatus[0];
                HelpScoutUserListStatusColor = UserListWindowLogic.HelpScoutUserListStatusColors[0];
                ReverifyUserList();
            }
            else
            {
                HelpScoutUserListStatus = UserListWindowLogic.HelpScutUseListStringStatus[1];
                HelpScoutUserListStatusColor = UserListWindowLogic.HelpScoutUserListStatusColors[1];
            }

            m_HelpScoutUserListLoaded = value; 
            RaisePropertyChanged("HelpScoutUserListLoaded"); 
        }
    }

    private List<User> m_HelpScoutUsersList;
    public List<User> HelpScoutUsersList
    {
        get { return m_HelpScoutUsersList; }
        set { m_HelpScoutUsersList = value; RaisePropertyChanged("HelpScoutUsersList"); }
    }

    private List<string> m_HelpScoutUsersListStrings = new List<string>();
    public List<string> HelpScoutUsersListStrings
    {
        get { return m_HelpScoutUsersListStrings; }
        set { m_HelpScoutUsersListStrings = value; RaisePropertyChanged("HelpScoutUsersListStrings"); }
    }

    public async void RetrieveHelpScoutUserList()
    {
        Task<List<User>> task = new Task<List<User>>(() => UserListWindowLogic.RetrieveHelpScoutUserList());
        task.Start();
        List<User> usersList = await task;
        if(usersList != null)
        {
            HelpScoutUsersList = usersList;
            foreach(User userObject in usersList)
            {
                HelpScoutUsersListStrings.Add(userObject.Name);
            }
            HelpScoutUserListLoaded = true;
        }
        else
        {
            HelpScoutUserListLoaded = false;
        }
    }

    private User MatchUserID(string name)
    {
        return UserListWindowLogic.FindUserByName(name, HelpScoutUsersList);
    }

    public void RemoveUser()
    {
        User user = UserListView.NamesDataGrid.SelectedItem as User;
        UsersList.Users.Remove(user);
        logger.Log(LogLevel.Debug, "Removed User: " + user.Name);
    }

    public void AddUser()
    {
        if (!string.IsNullOrEmpty(NewUserName) && HelpScoutUserListLoaded)
        {
            User user = MatchUserID(NewUserName);
            if(user != null)
            {
                UsersList.Users.Add(user);
                logger.Log(LogLevel.Debug, "Added New Valid User: " + user.Name);
            }
            else
            {
                UsersList.Users.Add(new User() { Name = NewUserName });
                logger.Log(LogLevel.Debug, "Added New User: " + NewUserName);
            }
        }
        else
        {
            UsersList.Users.Add(new User() { Name = NewUserName });
            logger.Log(LogLevel.Debug, "Added New User: " + NewUserName);
        }
        ClearNewUserNameTextBox();
    }

    //Clears the new user textbox
    public void ClearNewUserNameTextBox()
    {
        NewUserName = string.Empty;
    }

    public void SetupFreshViewModel()
    {
        m_HelpScoutUserListLoaded = false;
        HelpScoutUserListStatusColor = new SolidColorBrush(Color.FromArgb(255, 187, 95, 32));
        HelpScoutUserListStatus = "Attempting To Load HelpScout Users...";
        LoadUserList();
        RetrieveHelpScoutUserList();
    }

    public void SaveUserList()
    {
        UserListWindowLogic.SaveUserList(this);
        logger.Log(LogLevel.Debug, "Saved Users List");
        CloseFlyout();
    }

    public void ReverifyUserList()
    {
        UserListWindowLogic.CheckUserListValidity(HelpScoutUsersList);
        LoadUserList();
    }

    public void LoadUserList()
    {
        UserList userList;
        if(ApplicationData.Users != null)
        {
            userList = XMLSerialize<UserList>.CopyData(ApplicationData.Users);
        }
        else
        {
            userList = UserListWindowLogic.CreateNewUserList();
        }
        UsersList = userList;
    }

    public void ResetUserList()
    {
        UsersList = new UserList();
        logger.Log(LogLevel.Debug, "Reset Users List");
    }

    public void CloseFlyout()
    {
        MainWindow.UserListFlyout.IsOpen = false;
        logger.Log(LogLevel.Info, "Closed Users List Flyout");
    }
}

public class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public void RaisePropertyChanged(String propertyName)
    {
        PropertyChangedEventHandler temp = PropertyChanged;
        if (temp != null)
        {
            temp(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public bool IsInDesignMode
    {
        get
        {
            var prop = DesignerProperties.IsInDesignModeProperty;
            return (bool)DependencyPropertyDescriptor
                .FromProperty(prop, typeof(FrameworkElement))
                .Metadata.DefaultValue;
        }
    }
}

如果不看那些文件的内容或者您不向我们展示完整的异常,这段代码并没有真正帮助到您。您所提供的代码看起来完全没问题,但请给我们更多关于 NullReference 异常的细节,这样我们可能会进一步得到解决。 - Icepickle
当然,出于好奇,我在像XAML设计师这样的异常情况下如何获取更多详细信息?我尝试了打开第二个VS实例,将调试附加到VS#1的进程上,并在任何异常情况下使其中断,但什么也没有得到。我现在会发布ViewModels的内部内容。它们有点混乱,因为这一切都还在进行中。 - Douglas Gaskell
通常切换到设计模式时,设计师会提供一个“显示堆栈跟踪”选项,不是吗?如果错误窗口在设计模式下显示了错误,你还可以检查它。 - Icepickle
1个回答

2

如果您在构造函数中使用了一些不能在设计时初始化的依赖项,请确保您的视图模型的构造函数可以在设计时初始化,并将它们放在条件块中:if(!IsInDesignMode)


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