WPF: динамические просмотры на основе нажатий кнопок
Я новичок в WPF и, хотя я прочитал много теорий и статей, я не могу собрать все это в рабочее решение.
В настоящее время я хочу реализовать динамические множественные представления в окне, которое может быть выбрано пользователем с помощью кнопок. Цель очень похожа на приведенную в вопросе, WPF: динамическое представление / контент
Может кто-нибудь, пожалуйста, поделитесь со мной рабочим кодом, простейшей реализации вышеизложенного. Просто окно, которое содержит две сетки - одна сетка имеет две кнопки - вторая сетка меняет цвет фона в зависимости от того, какая кнопка нажата. С этого момента я могу пойти дальше.
Большое спасибо.
1 ответ
Используйте MVVM
Это дизайнерский подход. в основном вы относитесь к своим Window
как оболочка и он отвечает за обмен мнениями.
чтобы упростить этот фрагмент, ссылка на iv'e MvvmLight
Window
содержит ContentControl
который динамически отображает соответствующий вид
Каждый динамический вид может общаться с оболочкой Window
(используя MvvmLight's Messenger
) и прикажи ему поменять вид на что то другое
MainWindow.xaml
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:MainWindowViewModel></local:MainWindowViewModel>
</Window.DataContext>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button Grid.Row="0" Grid.Column="0" Command="{Binding ChangeFirstViewCommand}">Change View #1</Button>
<Button Grid.Row="0" Grid.Column="1" Command="{Binding ChangeSecondViewCommand}">Change View #2</Button>
<ContentControl Grid.Row="1" Grid.ColumnSpan="2" Content="{Binding ContentControlView}"></ContentControl>
</Grid>
</Window>
MainWindowViewModel.cs
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
namespace WpfApplication1
{
public class MainWindowViewModel : ViewModelBase
{
private FrameworkElement _contentControlView;
public FrameworkElement ContentControlView
{
get { return _contentControlView; }
set
{
_contentControlView = value;
RaisePropertyChanged("ContentControlView");
}
}
public MainWindowViewModel()
{
Messenger.Default.Register<SwitchViewMessage>(this, (switchViewMessage) =>
{
SwitchView(switchViewMessage.ViewName);
});
}
public ICommand ChangeFirstViewCommand
{
get
{
return new RelayCommand(() =>
{
SwitchView("FirstView");
});
}
}
public ICommand ChangeSecondViewCommand
{
get
{
return new RelayCommand(() =>
{
SwitchView("SecondView");
});
}
}
public void SwitchView(string viewName)
{
switch (viewName)
{
case "FirstView":
ContentControlView = new FirstView();
ContentControlView.DataContext = new FirstViewModel() { Text = "This is the first View" };
break;
default:
ContentControlView = new SecondView();
ContentControlView.DataContext = new SecondViewModel() { Text = "This is the second View" };
break;
}
}
}
}
FirstView.xaml
<UserControl x:Class="WpfApplication1.FirstView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<StackPanel>
<Label>This is the second view</Label>
<Label Content="{Binding Text}" />
<Button Command="{Binding ChangeToSecondViewCommand}">Change to Second View</Button>
</StackPanel>
</UserControl>
FirstViewModel.cs
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
namespace WpfApplication1
{
public class FirstViewModel : ViewModelBase
{
private string _text;
public string Text
{
get { return _text; }
set
{
_text = value;
RaisePropertyChanged("Text");
}
}
public ICommand ChangeToSecondViewCommand
{
get
{
return new RelayCommand(() =>
{
Messenger.Default.Send<SwitchViewMessage>(new SwitchViewMessage { ViewName = "SecondView" });
});
}
}
}
}
SecondView.xaml
<UserControl x:Class="WpfApplication1.SecondView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<StackPanel>
<Label>This is the second view</Label>
<Label Content="{Binding Text}" />
<Button Command="{Binding ChangeToFirstViewCommand}">Change to First View</Button>
</StackPanel>
</UserControl>
SecondViewModel.cs
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
namespace WpfApplication1
{
public class SecondViewModel : ViewModelBase
{
private string _text;
public string Text
{
get { return _text; }
set
{
_text = value;
RaisePropertyChanged("Text");
}
}
public ICommand ChangeToFirstViewCommand
{
get
{
return new RelayCommand(() =>
{
Messenger.Default.Send<SwitchViewMessage>(new SwitchViewMessage { ViewName = "FirstView" });
});
}
}
}
}
SwitchViewMessage.cs
namespace WpfApplication1
{
public class SwitchViewMessage
{
public string ViewName { get; set; }
}
}