Изменить вид изнутри usercontrol - PullRequest
0 голосов
/ 05 июля 2019

Моя идея состоит в том, чтобы иметь окно с двумя элементами управления содержимым, которые меняются в разных представлениях. Например, мое приложение может начинаться с изображения приветствия в одном элементе управления контентом и кнопки ввода / выхода в другом. При нажатии кнопки ввода я хочу изменить вид приветствия на другой вид, а кнопки входа / выхода - на 3 другие кнопки.

Моя текущая проблема заключается в том, что попытка изменить представление приветствия нажатием кнопки ввода не работает, если я помещаю его в пользовательский элемент управления и размещаю его в элементе управления контентом. Я думаю, потому что я на самом деле создаю новый экземпляр моего MainViewModel вместо ссылки на существующий, но я не совсем уверен.

Как я могу сделать это, когда я нажимаю на мою кнопку в BottomPanelTwoButtonsView, мои HomeView изменяются на TestView?

Всего 4 просмотров:

HomeView - экран приветствия

TestView - другой вид

BottomPanelTwoButtonsView - кнопки входа / выхода

BottomPanelThreeButtonsView - еще 3 кнопки

Вот основной код, который у меня есть:

App.xaml.cs

public partial class App : Application
    {
        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);

            MainWindow app = new MainWindow();
            MainViewModel context = new MainViewModel();
            app.DataContext = context;
            app.Show();
        }
    }

MainWindow.xaml

<Window x:Class="MyApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:localViewModels="clr-namespace:MyApp.ViewModels"
        xmlns:localViews="clr-namespace:MyApp.Views"
        mc:Ignorable="d"
        Name="RootWindow"
        WindowStyle="None" ResizeMode="NoResize"
        Topmost="True"
        WindowStartupLocation="CenterScreen"
        WindowState="Maximized"
        Background="{StaticResource BackgroundSolidColorBrush}"
        ToolBarTray.IsLocked="True"
        NumberSubstitution.Substitution="European"
        Title="MyApp" Height="1920" Width="1080">
    <Window.Resources>
        <DataTemplate DataType="{x:Type localViewModels:HomeViewModel}">
            <localViews:HomeView />
        </DataTemplate>
        <DataTemplate DataType="{x:Type localViewModels:TestViewModel}">
            <localViews:TestView />
        </DataTemplate>
        <DataTemplate DataType="{x:Type localViewModels:BottomPanelTwoButtonsViewModel}">
            <localViews:BottomPanelTwoButtons />
        </DataTemplate>
        <DataTemplate DataType="{x:Type localViewModels:BottomPanelThreeButtonsViewModel}">
            <localViews:BottomPanelThreeButtons />
        </DataTemplate>
    </Window.Resources>
    <DockPanel Background="White">           
        <ContentControl Content="{Binding CurrentBottomPanelViewModel}" DockPanel.Dock="Bottom" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" Height="96" Width="1080">                
        </ContentControl>
        <ContentControl Content="{Binding CurrentPageViewModel}" HorizontalAlignment="Stretch" VerticalAlignment="Top" HorizontalContentAlignment="Stretch" Height="1824" Width="1080">               
        </ContentControl>
    </DockPanel>
</Window>
* ** 1038 1039 * MainViewModel.cs * ** 1040 1041 *
public class MainViewModel : ObservableObject
    {
        #region Fields

        private ICommand _changePageCommand;
        private IPageViewModel _currentPageViewModel;
        private IBottomPanelViewModel _currentBottomPanelViewModel;
        private ObservableCollection<IPageViewModel> _pageViewModels;

        #endregion

        public MainViewModel()
        {

            CurrentPageViewModel = new HomeViewModel();
            CurrentBottomPanelViewModel = new BottomPanelTwoButtonsViewModel();
            //CurrentBottomPanelViewModel = new BottomPanelThreeButtonsViewModel();

            PageViewModels.Add(new ScreeningsScheduleViewModel());
            PageViewModels.Add(new TestViewModel());
            PageViewModels.Add(CurrentPageViewModel);
        }

        #region Properties / Commands

        public ICommand ChangePageCommand
        {
            get
            {
                if (_changePageCommand == null)
                {
                    _changePageCommand = new RelayCommand(
                        p => ChangeViewModel((IPageViewModel)p),
                        p => p is IPageViewModel);
                }

                return _changePageCommand;
            }
        }

        public ObservableCollection<IPageViewModel> PageViewModels
        {
            get
            {
                if (_pageViewModels == null)
                {
                    _pageViewModels = new ObservableCollection<IPageViewModel>();
                }

                return _pageViewModels;
            }
            set
            {
                _pageViewModels = value;
                OnPropertyChanged("PageViewModels");
            }
        }

        public IPageViewModel CurrentPageViewModel
        {
            get => _currentPageViewModel;
            set
            {
                if (_currentPageViewModel != value)
                {
                    _currentPageViewModel = value;
                    OnPropertyChanged("CurrentPageViewModel");
                }
            }
        }

        public IBottomPanelViewModel CurrentBottomPanelViewModel
        {
            get => _currentBottomPanelViewModel;
            set
            {
                if (_currentBottomPanelViewModel != value)
                {
                    _currentBottomPanelViewModel = value;
                    OnPropertyChanged("CurrentBottomPanelViewModel");
                }
            }
        }

        #endregion

        #region Methods

        private void ChangeViewModel(IPageViewModel viewModel)
        {                
            if (!PageViewModels.Contains(viewModel))
            {
                PageViewModels.Add(viewModel);
            }

            CurrentPageViewModel = PageViewModels
                .FirstOrDefault(vm => vm == viewModel);    
        }

        #endregion
    }

BottomPanelTwoButtonsView.xaml

<UserControl x:Class="MyApp.Views.BottomPanelTwoButtons"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:mvm="clr-namespace:MyApp"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="1080">
    <UserControl.DataContext>
        <mvm:MainViewModel/>
    </UserControl.DataContext>
    <Grid Height="96" Background="White" Width="1080">
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Button Grid.Column="0" 
                Content="1"
                Command="{Binding DataContext.ChangePageCommand, Source={RelativeSource Mode=FindAncestor, AncestorType={x:Type mvm:MainViewModel}}, Mode=TwoWay}"
                CommandParameter="{Binding PageViewModels[2]}"
                IsEnabled="True"
                Style="{StaticResource RoundCornerButtonCyanFilledBig}" 
                />
        <Button Grid.Column="1" Style="{StaticResource RoundCornerButtonMagentaFilledBig}"/>
    </Grid>
</UserControl>

IPageViewModel.cs

public interface IPageViewModel
    {
        string Name { get; }
    }

ObservableObject.cs

public abstract class ObservableObject : INotifyPropertyChanged
    {
        [Conditional("DEBUG")]
        [DebuggerStepThrough]
        public virtual void VerifyPropertyName(string propertyName)
        {        
            if (TypeDescriptor.GetProperties(this)[propertyName] == null)
            {
                string msg = "Invalid property name: " + propertyName;

                if (!ThrowOnInvalidPropertyName)
                {
                    Debug.Fail(msg);
                }
                else
                {
                    throw new Exception(msg);
                }
            }
        }

        protected virtual bool ThrowOnInvalidPropertyName { get; private set; }

        public virtual void RaisePropertyChanged(string propertyName)
        {
            VerifyPropertyName(propertyName);
            OnPropertyChanged(propertyName);
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            this.VerifyPropertyName(propertyName);

            PropertyChangedEventHandler handler = this.PropertyChanged;
            if (handler != null)
            {
                var e = new PropertyChangedEventArgs(propertyName);
                handler(this, e);
            }
        }
    }

RelayCommand.cs

public class RelayCommand : ICommand
    {
        readonly Action<object> _execute;
        readonly Predicate<object> _canExecute;

        public RelayCommand(Action<object> execute)
            : this(execute, null)
        {
        }

        public RelayCommand(Action<object> execute, Predicate<object> canExecute)
        {
            _execute = execute ?? throw new ArgumentNullException("execute");
            _canExecute = canExecute;
        }

        [DebuggerStepThrough]
        public bool CanExecute(object parameters)
        {
            return _canExecute == null ? true : _canExecute(parameters);
        }

        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }

        public void Execute(object parameters)
        {
            _execute(parameters);
        }
    }

1 Ответ

0 голосов
/ 05 июля 2019

Я думаю, что ваша проблема в пределах BottomPanelTwoButtonsView.xaml

Там у вас есть следующие строки:

<UserControl.DataContext>
    <mvm:MainViewModel/>
</UserControl.DataContext>

Итак, вы перезаписываете свой текстовый текст данных, который определен в Window.Resources MainWindow

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...