?一.實(shí)現(xiàn)左側(cè)菜單綁定
效果圖:
1.首先需要在項(xiàng)目中創(chuàng)建?mvvm 的架構(gòu)模式
- ? 創(chuàng)建 Models ,放置實(shí)體類。
實(shí)體類需要繼承自Prism 框架的?BindableBase,目的是讓實(shí)體類支持?jǐn)?shù)據(jù)的動(dòng)態(tài)變更!
- ?例如: 系統(tǒng)導(dǎo)航菜單實(shí)體類
/ <summary>
/// 系統(tǒng)導(dǎo)航菜單實(shí)體類
/// </summary>
public class MenuBar:BindableBase
{
private string icon;
/// <summary>
/// 菜單圖標(biāo)
/// </summary>
public string Icon
{
get { return icon; }
set { icon = value; }
}
private string title;
/// <summary>
/// 菜單名稱
/// </summary>
public string Title
{
get { return title; }
set { title = value; }
}
private string nameSpace;
/// <summary>
/// 菜單命名空間
/// </summary>
public string NameSpace
{
get { return nameSpace; }
set { nameSpace = value; }
}
}
- 創(chuàng)建View文件夾? 放置前端顯示頁面 。例如:創(chuàng)建首頁:MainView.xaml
- 創(chuàng)建ViewModel 文件夾,放置前端邏輯處理類。意思是:有前端頁面同時(shí),也要有對(duì)應(yīng)的后臺(tái)業(yè)務(wù)邏輯處理類。例如:MainViewModel
?
- 使用了Prism 框架,一些視圖或類的定義都是有約定的。例如:視圖統(tǒng)一使用xxxView?結(jié)尾。視圖模形統(tǒng)一使用xxxViewModel 結(jié)尾。這樣做的原因是:第一規(guī)范,第二,方便使用 Prism 進(jìn)行動(dòng)態(tài)的方式綁定上下文的時(shí)候,能自動(dòng)找到對(duì)應(yīng)類。
- Prism 動(dòng)態(tài)上下文綁定方式,引入命名空間,把 AutoWireViewModel 設(shè)置成 True
xmlns:prism="http://prismlibrary.com/" prism:ViewModelLocator.AutoWireViewModel="True"
2.創(chuàng)建MainViewModel 邏輯處理類
MainViewModel 類同樣也需要繼承自Prism 框架的?BindableBase?
- ?創(chuàng)建左側(cè)菜單的數(shù)據(jù),需要使用到一個(gè)動(dòng)態(tài)的屬性集合 ObservableCollection 來存放菜單的數(shù)據(jù)
- 創(chuàng)建菜單數(shù)據(jù)
public class MainViewModel: BindableBase
{
public MainViewModel()
{
MenuBars=new ObservableCollection<MenuBar>();
CreateMenuBar();
}
private ObservableCollection<MenuBar> menuBars;
public ObservableCollection<MenuBar> MenuBars
{
get { return menuBars; }
set { menuBars = value; RaisePropertyChanged(); }
}
void CreateMenuBar()
{
MenuBars.Add(new MenuBar() { Icon="Home",Title="首頁",NameSpace="IndexView"});
MenuBars.Add(new MenuBar() { Icon = "NotebookCheckOutline", Title = "待辦事項(xiàng)", NameSpace = "ToDoView" });
MenuBars.Add(new MenuBar() { Icon = "NotebookPlusOutline", Title = "忘備錄", NameSpace = "MemoView" });
MenuBars.Add(new MenuBar() { Icon = "Cog", Title = "設(shè)置", NameSpace = "SettingsView" });
}
}
- NameSpace:主要用于導(dǎo)航
- Icon:是Material DesignThemes UI 框架里面的圖標(biāo)名稱
3.MainView.xaml 前端綁定數(shù)據(jù)
- ?列表數(shù)據(jù)的綁定,使用ListBox 的自定義模板,也就是?ListBox.ItemTemplate,并且寫法是固定的
<!--列表-->
<ListBox>
<ListBox.ItemTemplate>
<DataTemplate>
<!--在這里添加內(nèi)容數(shù)據(jù)-->
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
- 例如:結(jié)合上面創(chuàng)建MainViewModel 類,給MainView.xaml 渲染數(shù)據(jù)
<!--列表-->
<ListBox ItemsSource="{Binding MenuBars}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="{Binding Icon}" Margin="15,0" />
<TextBlock Text="{Binding Title}" Margin="10,0"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
- ?MainView.xaml 添加動(dòng)態(tài)綁定 上下文
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
注意:項(xiàng)目中的MainWindow.xaml 已經(jīng)改成了MainView.xaml,并且把啟動(dòng)頁設(shè)置成 MainView了
- 最終項(xiàng)目結(jié)構(gòu)?
?4.左側(cè)菜單樣式調(diào)整
- 在App.xaml 資源文件中,更改默認(rèn)的主題顏色
- 更改左側(cè)列表選擇的樣式?
?重寫自定義樣式
- 在App.xaml 文件中 資源字典 ResourceDictionary 節(jié)點(diǎn)中,設(shè)置Style 屬性來進(jìn)行樣式重寫
Style 使用方式
- ?TargetType :設(shè)置作用的目標(biāo)類型
- ?Setter :設(shè)計(jì)器,里面有2個(gè)常用屬性,分別是Property 和Value。用來改變設(shè)置作用的目標(biāo)類型一些屬性的值
- key: 通過指定的key 來使用重寫的樣式
例如:設(shè)置ListBoxItem 屬性中的最小行高為40
<Style TargetType="ListBoxItem">
<Setter Property="MinHeight" Value="40"/>
</Style>
? ? ?3.?Property 中有一個(gè)特別的屬性:Template。用于改變控件的外觀樣式。并且也有固定的寫法
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
</ControlTemplate>
</Setter.Value>
</Setter>
?TargetType 有2種寫法
- 一種是直接用Style 設(shè)置一些屬性,可以這樣寫 TargetType="ListBoxItem"
- 另外一種寫法是,當(dāng)需要使用到自定義模板,也就是要改變控件的外觀樣式時(shí),Property 設(shè)置的值為?Template,里面TargetType 寫法就變成這樣?TargetType="{x:Type ListBoxItem}"
- 使用自定義的模板時(shí),需要使用到一個(gè)屬性?ContentPresenter,把原有模板的屬性原封不動(dòng)的投放到自定義模板。
? ? 4. 觸發(fā)器,它按條件應(yīng)用屬性值或執(zhí)行操作
?如果使用Template 自定義控件樣式后,需要搭配觸發(fā)器進(jìn)行使用。
例如:
<ControlTemplate TargetType="{x:Type ListBoxItem}"> <Grid> <!--內(nèi)容最左側(cè)的樣式--> <Border x:Name="borderHeader"/> <!--內(nèi)容選中的樣式--> <Border x:Name="border"/> <!--內(nèi)容呈現(xiàn),使用自定義模板時(shí),不加該屬性,原先的內(nèi)容無法呈現(xiàn)--> <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> </Grid> <!--觸發(fā)器--> <ControlTemplate.Triggers> <!--如果是選中狀態(tài)--> <Trigger Property="IsSelected" Value="True"> <!--第一個(gè)Border 設(shè)置邊框樣式--> <Setter Property="BorderThickness" TargetName="borderHeader" Value="4,0,0,0"/> <!--第一個(gè)Border 設(shè)置邊框顏色,value 動(dòng)態(tài)綁定主要是為了適應(yīng)主題顏色更改時(shí),邊框也著變--> <Setter Property="BorderBrush" TargetName="borderHeader" Value="{DynamicResource PrimaryHueLightBrush}"/> <!--第二個(gè)border 設(shè)置選中的樣式--> <Setter Property="Background" TargetName="border" Value="{DynamicResource PrimaryHueLightBrush}"/> <!--第二個(gè)border 設(shè)置選中的透明度--> <Setter Property="Opacity" TargetName="border" Value="0.2"/> </Trigger> <!--鼠標(biāo)懸停觸發(fā)器,如果鼠標(biāo)懸停時(shí)--> <Trigger Property="IsMouseOver" Value="True"> <!--第二個(gè)border 設(shè)置選中的樣式--> <Setter Property="Background" TargetName="border" Value="{DynamicResource PrimaryHueLightBrush}"/> <!--第二個(gè)border 設(shè)置選中的透明度--> <Setter Property="Opacity" TargetName="border" Value="0.2"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate>
? ?5. 樣式寫完后,需要在MainView.xmal 的ListBox中使用這個(gè)樣式資源文件,通過指定Key 來使用。文章來源:http://www.zghlxwxcb.cn/news/detail-714195.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-714195.html
?二.源碼
1.MainView.xaml
<Window x:Class="MyToDo.Views.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:MyToDo"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
WindowStyle="None" WindowStartupLocation="CenterScreen" AllowsTransparency="True"
Style="{StaticResource MaterialDesignWindow}"
TextElement.Foreground="{DynamicResource MaterialDesignBody}"
Background="{DynamicResource MaterialDesignPaper}"
TextElement.FontWeight="Medium"
TextElement.FontSize="14"
FontFamily="{materialDesign:MaterialDesignFont}"
mc:Ignorable="d"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
Title="MainWindow" Height="768" Width="1280">
<materialDesign:DialogHost DialogTheme="Inherit"
Identifier="RootDialog"
SnackbarMessageQueue="{Binding ElementName=MainSnackbar, Path=MessageQueue}">
<materialDesign:DrawerHost IsLeftDrawerOpen="{Binding ElementName=MenuToggleButton, Path=IsChecked}">
<!--左邊菜單-->
<materialDesign:DrawerHost.LeftDrawerContent>
<DockPanel MinWidth="220" >
<!--頭像-->
<StackPanel DockPanel.Dock="Top" Margin="0,20">
<Image Source="/Images/user.jpg" Width="50" Height="50">
<Image.Clip>
<EllipseGeometry Center="25,25" RadiusX="25" RadiusY="25" />
</Image.Clip>
</Image>
<TextBlock Text="WPF gg" Margin="0,10" HorizontalAlignment="Center" />
</StackPanel>
<!--列表-->
<ListBox ItemContainerStyle="{StaticResource MyListBoxItemStyle}" ItemsSource="{Binding MenuBars}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Background="Transparent">
<materialDesign:PackIcon Kind="{Binding Icon}" Margin="15,0" />
<TextBlock Text="{Binding Title}" Margin="10,0"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DockPanel>
</materialDesign:DrawerHost.LeftDrawerContent>
<DockPanel >
<!--導(dǎo)航條色塊-->
<materialDesign:ColorZone Padding="16" x:Name="ColorZone"
materialDesign:ElevationAssist.Elevation="Dp4"
DockPanel.Dock="Top"
Mode="PrimaryMid">
<DockPanel LastChildFill="False">
<!--上左邊內(nèi)容-->
<StackPanel Orientation="Horizontal">
<ToggleButton x:Name="MenuToggleButton"
AutomationProperties.Name="HamburgerToggleButton"
IsChecked="False"
Style="{StaticResource MaterialDesignHamburgerToggleButton}" />
<Button Margin="24,0,0,0"
materialDesign:RippleAssist.Feedback="{Binding RelativeSource={RelativeSource Self}, Path=Foreground, Converter={StaticResource BrushRoundConverter}}"
Command="{Binding MovePrevCommand}"
Content="{materialDesign:PackIcon Kind=ArrowLeft,
Size=24}"
Foreground="{Binding RelativeSource={RelativeSource AncestorType={x:Type FrameworkElement}}, Path=(TextElement.Foreground)}"
Style="{StaticResource MaterialDesignToolButton}"
ToolTip="Previous Item" />
<Button Margin="16,0,0,0"
materialDesign:RippleAssist.Feedback="{Binding RelativeSource={RelativeSource Self}, Path=Foreground, Converter={StaticResource BrushRoundConverter}}"
Command="{Binding MoveNextCommand}"
Content="{materialDesign:PackIcon Kind=ArrowRight,
Size=24}"
Foreground="{Binding RelativeSource={RelativeSource AncestorType={x:Type FrameworkElement}}, Path=(TextElement.Foreground)}"
Style="{StaticResource MaterialDesignToolButton}"
ToolTip="Next Item" />
<TextBlock Margin="16,0,0,0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
AutomationProperties.Name="Material Design In XAML Toolkit"
FontSize="22"
Text="筆記本" />
</StackPanel>
<!--上右邊圖標(biāo)-->
<StackPanel DockPanel.Dock="Right" Orientation="Horizontal">
<Image Source="/Images/user.jpg" Width="25" Height="25">
<Image.Clip>
<EllipseGeometry Center="12.5,12.5" RadiusX="12.5" RadiusY="12.5" />
</Image.Clip>
</Image>
<Button x:Name="btnMin" Style="{StaticResource MaterialDesignFlatMidBgButton}">
<materialDesign:PackIcon Kind="MoveResizeVariant" />
</Button>
<Button x:Name="btnMax" Style="{StaticResource MaterialDesignFlatMidBgButton}">
<materialDesign:PackIcon Kind="CardMultipleOutline" />
</Button>
<Button x:Name="btnClose" Style="{StaticResource MaterialDesignFlatMidBgButton}" Cursor="Hand">
<materialDesign:PackIcon Kind="WindowClose" />
</Button>
</StackPanel>
</DockPanel>
</materialDesign:ColorZone>
</DockPanel>
</materialDesign:DrawerHost>
</materialDesign:DialogHost>
</Window>
2.MainViewModel
namespace MyToDo.ViewModels
{
public class MainViewModel: BindableBase
{
public MainViewModel()
{
MenuBars=new ObservableCollection<MenuBar>();
CreateMenuBar();
}
private ObservableCollection<MenuBar> menuBars;
public ObservableCollection<MenuBar> MenuBars
{
get { return menuBars; }
set { menuBars = value; RaisePropertyChanged(); }
}
void CreateMenuBar()
{
MenuBars.Add(new MenuBar() { Icon="Home",Title="首頁",NameSpace="IndexView"});
MenuBars.Add(new MenuBar() { Icon = "NotebookCheckOutline", Title = "待辦事項(xiàng)", NameSpace = "ToDoView" });
MenuBars.Add(new MenuBar() { Icon = "NotebookPlusOutline", Title = "忘備錄", NameSpace = "MemoView" });
MenuBars.Add(new MenuBar() { Icon = "Cog", Title = "設(shè)置", NameSpace = "SettingsView" });
}
}
}
3.App.xaml
<prism:PrismApplication x:Class="MyToDo.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyToDo"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:prism="http://prismlibrary.com/">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<materialDesign:BundledTheme BaseTheme="Dark" PrimaryColor="DeepPurple" SecondaryColor="Lime" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
</ResourceDictionary.MergedDictionaries>
<Style x:Key="MyListBoxItemStyle" TargetType="ListBoxItem">
<Setter Property="MinHeight" Value="40"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Grid>
<!--內(nèi)容最左側(cè)的樣式-->
<Border x:Name="borderHeader"/>
<!--內(nèi)容選中的樣式-->
<Border x:Name="border"/>
<!--內(nèi)容呈現(xiàn),使用自定義模板時(shí),不加該屬性,原先的內(nèi)容無法呈現(xiàn)-->
<ContentPresenter
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
<!--觸發(fā)器-->
<ControlTemplate.Triggers>
<!--如果是選中狀態(tài)-->
<Trigger Property="IsSelected" Value="True">
<!--第一個(gè)Border 設(shè)置邊框樣式-->
<Setter Property="BorderThickness" TargetName="borderHeader" Value="4,0,0,0"/>
<!--第一個(gè)Border 設(shè)置邊框顏色,value 動(dòng)態(tài)綁定主要是為了適應(yīng)主題顏色更改時(shí),邊框也著變-->
<Setter Property="BorderBrush" TargetName="borderHeader" Value="{DynamicResource PrimaryHueLightBrush}"/>
<!--第二個(gè)border 設(shè)置選中的樣式-->
<Setter Property="Background" TargetName="border" Value="{DynamicResource PrimaryHueLightBrush}"/>
<!--第二個(gè)border 設(shè)置選中的透明度-->
<Setter Property="Opacity" TargetName="border" Value="0.2"/>
</Trigger>
<!--鼠標(biāo)懸停觸發(fā)器,如果鼠標(biāo)懸停時(shí)-->
<Trigger Property="IsMouseOver" Value="True">
<!--第二個(gè)border 設(shè)置選中的樣式-->
<Setter Property="Background" TargetName="border" Value="{DynamicResource PrimaryHueLightBrush}"/>
<!--第二個(gè)border 設(shè)置選中的透明度-->
<Setter Property="Opacity" TargetName="border" Value="0.2"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
</Application.Resources>
</prism:PrismApplication>
到了這里,關(guān)于Wpf 使用 Prism 實(shí)戰(zhàn)開發(fā)Day03的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!