Muy bien, continuemos con el tutorial, ahora agregaremos los botones para cerrar, maximizar y minimizar la ventana, diseñar el encabezado de la sección y abrir las vistas secundarias en el contenido de la sección.
Tutorial
Código
Estilos de botón
<!--Control bar button--> <Style x:Key="controlButton" TargetType="Button"> <!--Normal button style--> <Setter Property="Width" Value="35"/> <Setter Property="Background" Value="Transparent"/> <Setter Property="Foreground" Value="{StaticResource plainTextColor3}"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Button"> <Border Background="{TemplateBinding Background}" CornerRadius="4"> <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/> </Border> </ControlTemplate> </Setter.Value> </Setter> <Style.Triggers> <!--Button Style on hover--> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Background" Value="{StaticResource panelActiveColor}"/> <Setter Property="Foreground" Value="{Binding Path=Tag, RelativeSource={RelativeSource Self}}"/> </Trigger> </Style.Triggers> </Style> <!--Menu button icon--> <Style x:Key="controlButtonIcon" TargetType="fa:IconImage"> <Setter Property="Foreground" Value="{Binding Path=Foreground, RelativeSource={RelativeSource AncestorType=Button}}"/> <Setter Property="Width" Value="9"/> <Setter Property="Height" Value="9"/> </Style> <!--Icon button--> <Style x:Key="iconButton" TargetType="Button"> <!--Normal button style--> <Setter Property="Cursor" Value="Hand"/> <Setter Property="Width" Value="25"/> <Setter Property="Background" Value="Transparent"/> <Setter Property="Foreground" Value="{StaticResource plainTextColor1}"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Button"> <Border Background="{TemplateBinding Background}"> <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/> </Border> </ControlTemplate> </Setter.Value> </Setter> <Style.Triggers> <!--Button Style on hover--> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Foreground" Value="{Binding Path=Tag, RelativeSource={RelativeSource Self}}"/> </Trigger> </Style.Triggers> </Style> <!--Menu button icon--> <Style x:Key="iconButtonIcon" TargetType="fa:IconImage"> <Setter Property="Foreground" Value="{Binding Path=Foreground, RelativeSource={RelativeSource AncestorType=Button}}"/> <Setter Property="Width" Value="16"/> <Setter Property="Height" Value="16"/> </Style>
Modelos de Vista
ViewModelBase
public abstract class ViewModelBase : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
ViewModelCommand
public class ViewModelCommand : ICommand { //Fields private readonly Action<object> _executeAction; private readonly Predicate<object> _canExecuteAction; //Constructors public ViewModelCommand(Action<object> executeAction) { _executeAction = executeAction; _canExecuteAction = null; } public ViewModelCommand(Action<object> executeAction, Predicate<object> canExecuteAction) { _executeAction = executeAction; _canExecuteAction = canExecuteAction; } //Events public event EventHandler CanExecuteChanged { add { CommandManager.RequerySuggested += value; } remove { CommandManager.RequerySuggested -= value; } } //Methods public bool CanExecute(object parameter) { return _canExecuteAction == null ? true : _canExecuteAction(parameter); } public void Execute(object parameter) { _executeAction(parameter); } }
HomeViewModel
public class HomeViewModel : ViewModelBase { }
CustomerViewModel
public class CustomerViewModel : ViewModelBase { }
MainViewModel
public class MainViewModel : ViewModelBase { //Fields private UserAccountModel _currentUserAccount; private ViewModelBase _currentChildView; private string _caption; private IconChar _icon; private IUserRepository userRepository; //Properties public UserAccountModel CurrentUserAccount { get { return _currentUserAccount; } set { _currentUserAccount = value; OnPropertyChanged(nameof(CurrentUserAccount)); } } public ViewModelBase CurrentChildView { get { return _currentChildView; } set { _currentChildView = value; OnPropertyChanged(nameof(CurrentChildView)); } } public string Caption { get { return _caption; } set { _caption = value; OnPropertyChanged(nameof(Caption)); } } public IconChar Icon { get { return _icon; } set { _icon = value; OnPropertyChanged(nameof(Icon)); } } //--> Commands public ICommand ShowHomeViewCommand { get; } public ICommand ShowCustomerViewCommand { get; } public MainViewModel() { userRepository = new UserRepository(); CurrentUserAccount = new UserAccountModel(); //Initialize commands ShowHomeViewCommand = new ViewModelCommand(ExecuteShowHomeViewCommand); ShowCustomerViewCommand = new ViewModelCommand(ExecuteShowCustomerViewCommand); //Default view ExecuteShowHomeViewCommand(null); LoadCurrentUserData(); } private void ExecuteShowCustomerViewCommand(object obj) { CurrentChildView = new CustomerViewModel(); Caption = "Customers"; Icon = IconChar.UserGroup; } private void ExecuteShowHomeViewCommand(object obj) { CurrentChildView = new HomeViewModel(); Caption = "Dashboard"; Icon = IconChar.Home; }
Vistas
HomeView
<UserControl x:Class="WPF_LoginForm.Views.HomeView" 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" xmlns:local="clr-namespace:WPF_LoginForm.Views" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"> <Grid> <Image Source="/Images/dashboard-template.png"/> </Grid> </UserControl>
CustomerView
<UserControl x:Class="WPF_LoginForm.Views.CustomerView" 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" xmlns:local="clr-namespace:WPF_LoginForm.Views" xmlns:fa="http://schemas.awesome.incremented/wpf/xaml/fontawesome.sharp" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="50"/> <RowDefinition/> </Grid.RowDefinitions> <Grid Grid.Row="0"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="120"/> </Grid.ColumnDefinitions> <StackPanel Orientation="Horizontal" VerticalAlignment="Top" Grid.Column="0"> <fa:IconImage Icon="Search" Height="20" Width="20" Foreground="{StaticResource plainTextColor3}"/> <TextBox Text="Search..." FontSize="13" Height="24" Width="300" Background="Transparent" FontWeight="Medium" FontFamily="Montserrat" Foreground="{StaticResource plainTextColor3}" CaretBrush="{StaticResource plainTextColor3}" BorderBrush="{StaticResource plainTextColor3}" BorderThickness="0,0,0,1" VerticalContentAlignment="Center" Margin="5,5,0,0"></TextBox> </StackPanel> <Button Grid.Column="1" Command="{Binding LoginCommand}" Content="Search" FontSize="12" FontFamily="Montserrat" Cursor="Hand" BorderThickness="0" Foreground="White" VerticalAlignment="Top"> <Button.Style> <Style TargetType="Button"> <Setter Property="Background" Value="#773DFF"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Button"> <Border Height="30" CornerRadius="15" Background="{TemplateBinding Background}"> <ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center"/> </Border> </ControlTemplate> </Setter.Value> </Setter> <Style.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Background" Value="#836EFB"/> </Trigger> </Style.Triggers> </Style> </Button.Style> </Button> </Grid> <Border Grid.Row="1" Background="#200F53" CornerRadius="10" Padding="10"> <DataGrid ColumnWidth="*" Background="#200F53" BorderThickness="0"> <DataGrid.ColumnHeaderStyle> <Style TargetType="DataGridColumnHeader"> <Setter Property="Background" Value="Transparent"/> <Setter Property="Foreground" Value="#BCBEE0"/> <Setter Property="Padding" Value="10,0,0,10"/> <Setter Property="FontFamily" Value="Montserrat"/> <Setter Property="FontSize" Value="15"/> </Style> </DataGrid.ColumnHeaderStyle> <DataGrid.Columns> <DataGridTextColumn Binding="{x:Null}" ClipboardContentBinding="{x:Null}" Header="ID" HeaderStringFormat=""/> <DataGridTextColumn Binding="{x:Null}" ClipboardContentBinding="{x:Null}" Header="First name"/> <DataGridTextColumn Binding="{x:Null}" ClipboardContentBinding="{x:Null}" Header="Last name"/> <DataGridTextColumn Binding="{x:Null}" ClipboardContentBinding="{x:Null}" Header="Phone"/> <DataGridTextColumn Binding="{x:Null}" ClipboardContentBinding="{x:Null}" Header="Number"/> <DataGridTextColumn Binding="{x:Null}" ClipboardContentBinding="{x:Null}" Header="Address"/> </DataGrid.Columns> </DataGrid> </Border> </Grid> </UserControl>
MainView
<Window.DataContext> <viewModel:MainViewModel/> </Window.DataContext> <Window.Resources> <DataTemplate DataType="{x:Type viewModel:HomeViewModel}"> <local:HomeView/> </DataTemplate> <DataTemplate DataType="{x:Type viewModel:CustomerViewModel}"> <local:CustomerView/> </DataTemplate> </Window.Resources> <!--Here previous code... get previous code in previous tutorial--> <!--Control bar--> <StackPanel x:Name="pnlControlBar" Grid.Row="0" Orientation="Horizontal" FlowDirection="RightToLeft" Background="Transparent" Margin="0,0,5,0" MouseLeftButtonDown="pnlControlBar_MouseLeftButtonDown" MouseEnter="pnlControlBar_MouseEnter"> <Button x:Name="btnClose" Style="{StaticResource controlButton}" Tag="{StaticResource color4}" Click="btnClose_Click"> <fa:IconImage Icon="Xmark" Style="{StaticResource controlButtonIcon}"/> </Button> <Button x:Name="btnMaximize" Style="{StaticResource controlButton}" Tag="{StaticResource color6}" Click="btnMaximize_Click"> <fa:IconImage Icon="Square" Style="{StaticResource controlButtonIcon}"/> </Button> <Button x:Name="btnMinimize" Style="{StaticResource controlButton}" Tag="{StaticResource color8}" Click="btnMinimize_Click"> <fa:IconImage Icon="WindowMinimize" Width="12" Style="{StaticResource controlButtonIcon}"/> </Button> </StackPanel> <!--Header / Caption--> <Grid Grid.Row="1"> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <!--Caption--> <StackPanel Grid.Column="0" Orientation="Horizontal" VerticalAlignment="Center"> <fa:IconImage Icon="{Binding Icon}" Height="20" Width="20" Foreground="{StaticResource titleColor2}" Margin="35,0,10,0"/> <TextBlock Text="{Binding Caption}" Foreground="{StaticResource titleColor2}" FontSize="16" FontFamily="Montserrat" FontWeight="Medium" VerticalAlignment="Center"/> </StackPanel> <!--User options--> <StackPanel Grid.Column="1" Orientation="Horizontal" FlowDirection="RightToLeft" VerticalAlignment="Center" Margin="0,0,10,0"> <Button Style="{StaticResource iconButton}" Tag="{StaticResource color1}"> <fa:IconImage Icon="AngleDown" Height="12" Width="12" Style="{StaticResource iconButtonIcon}"/> </Button> <TextBlock Text="{Binding CurrentUserAccount.DisplayName}" Foreground="{StaticResource titleColor3}" FontFamily="Montserrat" FontSize="12" VerticalAlignment="Center"/> <Ellipse Height="35" Width="35" Stroke="{StaticResource color2}" StrokeThickness="2" Margin="10,0,10,0"> <Ellipse.Fill> <ImageBrush ImageSource="/Images/profile-picture.png"/> </Ellipse.Fill> </Ellipse> <Button Style="{StaticResource iconButton}" Tag="{StaticResource color3}"> <fa:IconImage Icon="Clock" Style="{StaticResource iconButtonIcon}"/> </Button> <Button Style="{StaticResource iconButton}" Tag="{StaticResource color4}"> <fa:IconImage Icon="Envelope" Style="{StaticResource iconButtonIcon}"/> </Button> <Button Style="{StaticResource iconButton}" Tag="{StaticResource color5}"> <fa:IconImage Icon="Bell" Style="{StaticResource iconButtonIcon}"/> </Button> </StackPanel> </Grid> <!--Content section / Child views--> <ContentControl Content="{Binding CurrentChildView}" Grid.Row="2" Margin="25"/> </Grid> </Border> </Grid> </Border> </Window>