我是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
我編輯了我的答案 –