Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/274.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# MVVM无法在主页上显示默认用户控件_C#_Wpf_Mvvm - Fatal编程技术网

C# MVVM无法在主页上显示默认用户控件

C# MVVM无法在主页上显示默认用户控件,c#,wpf,mvvm,C#,Wpf,Mvvm,我正在使用WPF创建一个应用程序,并尝试使用MVVM模式 我有一个主窗口,其中设置了一些在整个应用程序中使用的默认控件。 在这个主窗口中,我设置了一个ContentControl来显示不同的子视图,具体取决于按下的导航按钮 在大多数情况下,这很好。实际的导航功能正常,因此我不太关心该代码。将显示主窗口,当我按下按钮时,所需的ContentControl将显示数据库中的正确信息 我遇到的问题是试图显示默认的ContentControl。当MainWindow首次加载时,我希望显示“主”Conten

我正在使用WPF创建一个应用程序,并尝试使用MVVM模式

我有一个主窗口,其中设置了一些在整个应用程序中使用的默认控件。
在这个主窗口中,我设置了一个ContentControl来显示不同的子视图,具体取决于按下的导航按钮

在大多数情况下,这很好。实际的导航功能正常,因此我不太关心该代码。将显示主窗口,当我按下按钮时,所需的ContentControl将显示数据库中的正确信息

我遇到的问题是试图显示默认的ContentControl。当MainWindow首次加载时,我希望显示“主”ContentControl,而不必按下按钮

以下是我现在拥有的:

MainWindowVM:

public class MainWindowVM : ViewModelBase
{
    public MainWindowVM()
    {
        NavCommand = new NavigationCommand<string>(OnNav);
    }

    private MasterViewVM masterViewVM = new MasterViewVM();
    private Room1ViewVM room1ViewVM = new Room1ViewVM();
    private Room2ViewVM room2ViewVM = new Room2ViewVM();

    private ObservableObject currentViewModel;
    public ObservableObject CurrentViewModel
    {
        get { return currentViewModel; }
        set { SetProperty(ref currentViewModel, value); }
    }

    public NavigationCommand<string> NavCommand { get; private set; }

    private void OnNav(string destination)
    {
        switch (destination)
        {
            case "master":
                CurrentViewModel = masterViewVM;
                break;
            case "room1":
                CurrentViewModel = room1ViewVM;
                break;
            case "room2":
                CurrentViewModel = room2ViewVM;
                break;
        }
}
<Window.Resources>
    <DataTemplate DataType="{x:Type viewModels:MasterViewVM}">
        <views:MasterView/>
    </DataTemplate>
    <DataTemplate DataType="{x:Type viewModels:Room1ViewVM}" >
        <views:Room1View />
    </DataTemplate>
    <DataTemplate DataType="{x:Type viewModels:Room2ViewVM}" >
        <views:Room2View />
    </DataTemplate>
</Window.Resources>

<Grid>
    <StackPanel Name="stackPage" Orientation="Vertical" Grid.Column="1">

        <StackPanel Name="stackNavButtons"
                Orientation="Horizontal"
                Grid.Column="1" Grid.ColumnSpan="4"
                Grid.Row="1"
                HorizontalAlignment="Center"
                VerticalAlignment="Center"
                >
            <Button Name="btnMaster"
            Content="Master"                    
            Height="50"
            Width="75"
            Command="{Binding NavCommand}"
            CommandParameter="master"
            />
            <Button Name="btnRoom1"
            Content="Room 1"                    
            Height="50"
            Width="75"
            Command="{Binding NavCommand}"
            CommandParameter="room1"
            />
            <Button Name="btnRoom2"
            Content="Room 2"                    
            Height="50"
            Width="75"
            Command="{Binding NavCommand}"
            CommandParameter="room2"
            />
        </StackPanel>

        <ContentControl Content="{Binding CurrentViewModel}" />

    </StackPanel>
</Grid>
为了在打开主窗口(并试图显示主窗口)之前加载数据,我尝试将以下内容添加到上述方法中

我最后一次尝试是完全按照Rachel Lim的博客中提供的指导来重建程序。 我不打算在这里包含修改过的代码,因为我最终得到了相同的结果

我能够让Rachel的示例应用程序正常工作。但是,它没有连接到数据库。这进一步表明,我的问题在于何时和/或如何将数据加载到主视图中

我现在所要做的只是在显示MainWindow时让Master显示为初始ContentControl

编辑:根据IBebs的建议更改“currentViewModel”的大小写(大写改为小写)解决了这个问题。 现在,构造函数的内容如下:

    public MainWindowVM()
    {
        NavCommand = new NavigationCommand<string>(OnNav);
        currentViewModel = masterViewVM;
    }

我不确定这是否能更好地处理空值,但似乎有可能。

我担心问题中没有足够的信息可以肯定地回答(例如,您是否使用Microsoft.VisualStudio.PlatformUI库?ViewModelBase在哪里定义?)但我猜ViewModelBase在调用PropertyChanged事件之前不会检查null,该事件将由
SetProperty(ref currentViewModel,value)
调用调用

为了解决这个问题,我将:

a) 确保ViewModelBase在调用PropertyChanged事件之前检查null,该事件通常按以下方式执行(取自ObservableObject代码):

b) 将初始视图模型指定给字段而不是属性,这将不会导致触发属性更改事件。因此,建造商应:

public MainWindowVM()
{
    NavCommand = new NavigationCommand<string>(OnNav);
    currentViewModel = masterViewVM; // Note lower case 'c' on currentViewModel
}
publicMainWindowVM()
{
NavCommand=新导航命令(OnNav);
currentViewModel=masterViewVM;//注意currentViewModel上的小写字母“c”
}

希望有帮助。

恐怕问题中没有足够的信息可以肯定地回答(例如,您是否使用Microsoft.VisualStudio.PlatformUI库?ViewModelBase在哪里定义?)但我猜ViewModelBase在调用PropertyChanged事件之前不会检查null,该事件将由
SetProperty(ref currentViewModel,value)
调用调用

为了解决这个问题,我将:

a) 确保ViewModelBase在调用PropertyChanged事件之前检查null,该事件通常按以下方式执行(取自ObservableObject代码):

b) 将初始视图模型指定给字段而不是属性,这将不会导致触发属性更改事件。因此,建造商应:

public MainWindowVM()
{
    NavCommand = new NavigationCommand<string>(OnNav);
    currentViewModel = masterViewVM; // Note lower case 'c' on currentViewModel
}
publicMainWindowVM()
{
NavCommand=新导航命令(OnNav);
currentViewModel=masterViewVM;//注意currentViewModel上的小写字母“c”
}

希望有帮助。

完美!!非常感谢你。更改currentViewModel的案例解决了这个问题。完美!!非常感谢你。更改currentViewModel的案例解决了此问题。
public class ObservableObject : INotifyPropertyChanged
{

    protected virtual void SetProperty<T>(ref T member, T val, [CallerMemberName] string propertyName = null)
    {
        if (object.Equals(member, val)) return;

        member = val;
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
    protected void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        if (PropertyChanged == null)
            return;
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
protected void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
  PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
  if (propertyChanged == null)
    return;
  propertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public MainWindowVM()
{
    NavCommand = new NavigationCommand<string>(OnNav);
    currentViewModel = masterViewVM; // Note lower case 'c' on currentViewModel
}