我是wpf和xaml的新手,尝试在WindowsApplication(Xaml,WPF)中更改窗口的内容(登录 - >主内容和主内容 - >登录)。到目前为止,我已经在这个简单的登录/注销情况如下:通过ValueConverter更改MainWindow内容
BaseViewModel
public class BaseViewModel : DependencyObject, INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; public virtual void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
BaseMainViewViewModel(在主窗口设置MainViewType产业基地类它还包含了命令来改变。从BaseMainViewViewModel通过在MainViews按钮的属性。)
public class BaseMainViewViewModel : BaseViewModel { private static MainViewType _CurrentMainView; private ICommand _SwitchMainViewCommand; public BaseMainViewViewModel() { SwitchMainViewCommand = new RelayCommand(SwitchMainView); } public MainViewType CurrentMainView { get { return _CurrentMainView; } set { if (value != _CurrentMainView) { _CurrentMainView = value; OnPropertyChanged(nameof(CurrentMainView)); } } } public ICommand SwitchMainViewCommand { get { return _SwitchMainViewCommand; } set { _SwitchMainViewCommand = value; } } #region Test public void SwitchMainView(object param) { Debugger.Break(); switch (CurrentMainView) { case MainViewType.Login: CurrentMainView = MainViewType.Main; break; case MainViewType.Main: CurrentMainView = MainViewType.Login; break; default: break; } MessageBox.Show("Login/Logout"); } #endregion Test
LoginViewModel inherites得到交流塞斯的CurrentMainView,物业
public class LoginViewModel : BaseMainViewViewModel {}
MainViewModel她同样
public class MainViewModel : BaseMainViewViewModel {}
MainWindowViewModel
public class MainWindowViewModel: BaseMainViewViewModel {}
LoginMainView
public partial class LoginMainView : UserControl { public LoginMainView() { InitializeComponent(); DataContext = new LoginViewModel(); } }
目前我在LoginMainView中只有一个按钮(Login-Button)。如果我点击这个按钮,当前的LoginMainView应该与MainMainView交换。
<Grid> <Button Content="Main" Background="Red" Command="{Binding SwitchMainViewCommand}" /> </Grid>
MainMainView
public partial class MainMainView : UserControl { public LoginMainView() { InitializeComponent(); DataContext = new MainViewModel(); } }
同样在这里(退出键式)对应于LoginMainView ...
<Grid> <Button Content="Logout" Background="Green" Command="{Binding SwitchMainViewCommand}" /> </Grid>
主窗口
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); DataContext = new MainWindowViewModel(); } }
在MainWindow-查看我将CurrentMainView-Property(MainViewType)从BaseMainViewViewModel绑定到contentpresenter,我将通过单击MainMainView/LoginMainView中的按钮进行更改,然后使用ValueConverter进行更改。
<Grid> <StackPanel> <Label Content="Test" /> <ContentPresenter Content="{Binding CurrentMainView, Converter={view:MainViewValueConverter}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> </StackPanel> </Grid>
MainViewType
public enum MainViewType { Login = 0, Main = 1 }
BaseValueConverter
public abstract class BaseValueConverter<T> : MarkupExtension, IValueConverter where T : class, new() { private static T _Converter = null; public override object ProvideValue(IServiceProvider serviceProvider) { return _Converter ?? (_Converter = new T()); } public abstract object Convert(object value, Type targetType, object parameter, CultureInfo culture); public abstract object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture); }
RelayCommand
public class RelayCommand : ICommand { private Action<object> _Execute; private Predicate<object> _CanExecute; private event EventHandler CanExecuteChangedInternal; public RelayCommand(Action<object> execute) : this(execute, DefaultCanExecute) { } public RelayCommand(Action<object> execute, Predicate<object> canExecute) { _Execute = execute ?? throw new ArgumentNullException("execute"); _CanExecute = canExecute ?? throw new ArgumentNullException("canExecute"); } public event EventHandler CanExecuteChanged { add { CommandManager.RequerySuggested += value; CanExecuteChangedInternal += value; } remove { CommandManager.RequerySuggested -= value; CanExecuteChangedInternal -= value; } } public bool CanExecute(object parameter) { return (_CanExecute != null) && _CanExecute(parameter); } public void Execute(object parameter) { _Execute(parameter); } public void OnCanExecuteChanged() { EventHandler eventHandler = CanExecuteChangedInternal; if (eventHandler != null) { eventHandler.Invoke(this, EventArgs.Empty); } } public void Destroy() { _CanExecute = _ => false; _Execute = _ => { return; }; } private static bool DefaultCanExecute(object parameter) { return true; } }
当我启动应用程序时,调用ValueConverter并加载正确的View(LoginMainView)。然后,我单击LoginMainView中的按钮,执行命令(SwitchMainView),但是因为不使用ValueConverter,所以MainWindow的内容不会更改为MainMainView。
我在做什么错了?我有一个基本的理解问题吗?还是不可能以这种方式映射简单的登录/注销场景?或者我只是忽略了一些东西?有人能告诉我我忘了什么吗?
非常感谢提前帮助!
好吧,首先感谢您的答案。但要更好地学习和理解WPF和XAML,我想重新发明轮子。 ;-)那么我需要做什么才能以上述方式实现它?我还缺少什么?顺便说一句。我在哪里放'AppBootstraper.ActiveViewModel = new LoginViewModel()'?我是否必须为此创建两个命令,将它们绑定到相应的按钮? – srcalex
我编辑了我的答案 –