【发布时间】:2026-02-17 07:20:03
【问题描述】:
我有一个带有导航侧栏的主窗口和一个用户控件,其中我显示了 3 个视图(默认,view1,view2)。在主视图模型(称为 AppVM)中,我将 contentcontrol 初始化为默认视图,该视图有一个按钮可以前进到 view1(除了导航侧边栏)。我在 AppVM 中有命令可以切换到三个视图中的任何一个。 View1 然后有另一个按钮,它应该移动到 view2(使用主视图模型中的命令)。但是,每当我按下 view1 中的按钮(移动到 view2)时,显示都不会改变。奇特的是,在调试时,按下view1中的按钮时,内容控件绑定的变量设置为默认视图,而不是当前视图view1。
我认为我设置命令的方式是创建内容控件绑定变量的新实例,但我不知道如何使它使用相同的实例而不是一次又一次地打开新实例。
主视图模型 (AppVM)
public class AppVM : ObservableObject
{
//Create a property that controls current view
private object _currentView;
public object CurrentView
{
get { return _currentView; }
private set
{
OnPropertyChanged(ref _currentView, value);
}
}
private string _textboxText;
public string TextboxText
{
get { return _textboxText; }
set
{
OnPropertyChanged(ref _textboxText, value);
}
}
//Instantiate the relaycommands, we will need to instantiate relaycommand objects for every command we need to perform.
//This means that we will need to do this for preses of all buttons
public RelayCommand View1ButtonCommand { get; private set; }
public RelayCommand View2ButtonCommand { get; private set; }
public RelayCommand DefaultCommand { get; private set; }
public AppVM()
{
//CurrentView = this;
CurrentView = new DefaultVM();
View1ButtonCommand = new RelayCommand(ShowView1, AlwaysTrueCommand);
View2ButtonCommand = new RelayCommand(ShowView2, AlwaysTrueCommand);
DefaultCommand = new RelayCommand(ShowDefault, AlwaysTrueCommand);
}
public void ShowDefault(object dummy)
{
// CurrentView = null;
CurrentView = new DefaultVM();
}
public void ShowView1(object dummy)
{
//CurrentView = null;
CurrentView = new View1(dummy as string);
}
public void ShowView2(object dummy)
{
// CurrentView = null;
CurrentView = new View2();
}
public bool AlwaysTrueCommand(object dummy)
{
return true;
}
}
查看 1 个虚拟机
public class View1VM : ObservableObject {
public InfoClass View1InfoClass { get; set; }
public View1VM() { View1InfoClass = new InfoClass //Apparently I need to instantiate and initialize this to activate binding {
FirstName = "Abbas",
//FirstName = passedInforClass,
LastName = "Syed",
Number = 12
};
} }
view1.xaml 中的命令
<UserControl.Resources>
<vm:AppVM x:Name="AppVMinView1" x:Key="AppVMinView1"></vm:AppVM>
</UserControl.Resources>
<UserControl.DataContext>
<vm:View1VM></vm:View1VM>
</UserControl.DataContext>
<Grid Background="Aqua">
<StackPanel Margin="100">
<TextBlock Text="First Name"/>
<TextBox x:Name="firstNameTextBoxView1" Text="{Binding View1InfoClass.FirstName, Mode=OneWayToSource, UpdateSourceTrigger=PropertyChanged}"></TextBox>
<TextBlock Text="Last Name"/>
<TextBox x:Name="lastNameTextBoxView1" Text="{Binding View1InfoClass.LastName, Mode=OneWayToSource, UpdateSourceTrigger=PropertyChanged}"></TextBox>
<TextBlock Text="Random Useless Number" ></TextBlock>
<TextBox x:Name="randomUselessNumberView1" Text="{Binding View1InfoClass.Number, Mode=OneWayToSource, UpdateSourceTrigger=PropertyChanged}"></TextBox>
<TextBlock Text="First Name Entered"></TextBlock>
<TextBlock Text="{Binding View1InfoClass.FirstName}"></TextBlock>
<TextBlock Text="Last Name Entered" ></TextBlock>
<TextBlock Text="{Binding View1InfoClass.LastName}"></TextBlock>
<TextBlock Text="Random Useless Number Entered"></TextBlock>
<TextBlock Text="{Binding View1InfoClass.Number}"></TextBlock>
<Button DataContext="{DynamicResource AppVMinView1}" Content="Go to view2" Height="20" Width="70" Command="{Binding View2ButtonCommand}" />
</StackPanel>
</Grid>
根据我所阅读的内容(此处和互联网上),我需要将视图设为单例,我尝试这样做的方法是声明 view2 的静态属性,并使用私有设置器初始化为新的 view2,但是那没有削减它。对于这方面的任何帮助,我将不胜感激。
我还应该补充一点,即使 view1 中更改为 view2 的按钮不起作用,侧面导航栏按钮也可以正常工作。
【问题讨论】:
-
你的问题格式很奇怪。有些代码甚至没有显示。代码应该被格式化为代码而不是块引用。
-
您的
Button已磨损DataContext设置。DataContext必须是AppVM,否则Command绑定无法解析。将视图设为单例是没有用的。 -
你好 BionicCode。感谢您的回复并指出格式不正确(对不起!)我将它绑定到 AppVM,但是在调试时,单击 View1 中的按钮导航到 View2 时,我到达 AppVM 中的断点,但 CurrentView 变量设置为 DefaultVM(但它应该是 View1 [这是它的最后一个值])。
-
看起来您正在创建多个 AppVm 实例。确保您始终使用相同的实例。您正在修改的实例不是触发新视图的实例。
-
你好 BionicCode。谢谢你回到我身边。这就是我实际上感到困惑的部分。我读到可以声明主视图模型(AppVM)的静态属性以使用相同的实例。但是,由于我有非静态成员(命令),所以我不能有静态构造函数。还有另一种方法吗?如果我听起来很愚蠢,我很抱歉,这是我的第一个项目。感谢您抽出宝贵时间!
标签: c# wpf xaml user-controls