WPF framework custom Windows Metro Style form tutorial

Source: Internet
Author: User
Tags foreach xmlns

First look at the final form of the effect chart,



We can see from the screenshot that the form is made up of two parts, the top of which is the minimize and close button, and the other area is the display area of the form. Take a look at the specific implementation code below,

Metrowindow Style:

<resourcedictionary xmlns= "Http://schemas.microsoft.com/winfx/2006/xaml/presentation"                       xmlns:x= "Http://schemas.microsoft.com/winfx/2006/xaml"                      xmlns:local= "Clr-namespace: MetroWindow.Resources.Styles >     <!--Minimize button style-->     <style  x:key= "Winminbtnstyle"  targettype= "button" >         < Setter property= "Snapstodevicepixels"  value= "True"/>          <setter property= "Overridesdefaultstyle"  value= "True"/>          <setter property= "Width"  value= "/>"          <setter property= "Height " value=" "/>         <setter property=" VerticalAlignment " value=" Top "/>         <Setter  property= "Template" >             < Setter.value>                  <controltemplate targettype= "button" >                      <border x:name= "MainBorder"   background= "Transparent" >                          <Grid>                               <contentpresEnter content= ' {templatebinding content} '  horizontalalignment= ' {templatebinding 
Horizontalcontentalignment} " verticalalignment=" {templatebinding verticalcontentalignment} "/>                          </Grid>                      </Border>                      < Controltemplate.triggers>                          <trigger property= "IsMouseOver"  value= "True" >                         &nBsp;    <setter targetname= "Mainborder"  property= "Background"  Value= "# 33a58d "/>                          </Trigger>                      </controltemplate.triggers >                 </ Controltemplate>             </setter.value
>         </Setter>     </Style>     <!--Turn off button style-->     <style x:key= "Winclosebtnstyle"  targettype= "button" >         <setter property= " Snapstodevicepixels " value=" TrUE "/>         <setter property=" OverridesDefaultStyle "  Value= "True"/>         <setter property= "Width"  Value= "
/>         <setter property= "Height"  Value= "/>"         <setter property= "VerticalAlignment"  Value= "Top"/ >         <setter property= "Template" >              <Setter.Value>       
          <controltemplate targettype= "button" >                      <border x:name= "Mainborder"  background= "Transparent" >                           <Grid>                              <ContentPresenter  Horizontalalignment= ' {templatebinding horizontalcontentalignment} '  verticalalignment= ' { Templatebinding verticalcontentalignment} "/>                          </Grid>                       </Border>                      <ControlTemplate.Triggers>                &nbSp;         <trigger property= "IsMouseOver"  Value= " True ">                              <setter targetname= "MainBorder " property=" Background " value=" #d44c45 "/>          
               </Trigger>                      </ControlTemplate.Triggers>                  </ControlTemplate>         
    </Setter.Value>         </Setter>     </style>     <!--Form control template-->     <controltemplate x:key= "Metrowindowtemplate"  targettype= "{X:type window}" >          <border borderbrush= "#2a927c"  borderthickness= "1"  background= "white" >              <Grid>                  <Grid.RowDefinitions>                      < Rowdefinition height= "/>"                      <rowdefinition height= "*"/>                  </Grid.RowDefinitions>                  <grid grid.row= "0"  Background= "# 2a927c ">                      <Grid.ColumnDefinitions>                          <columndefinition  width= "Auto"/>                          <columndefinition width= "*"/>                           <columndefinition width= "Auto"/>                           <columndefinition&nBsp Width= "Auto"/>                      </Grid.ColumnDefinitions>                      <textblock x:name= " Windowtitletbl " grid.column=" 0 " text=" " fontfamily=" Microsoft yahei "  Verticalalignment= "Center"                                            fontsize= " fontweight=" "Bold"  margin= "10,0"   foreground= "White"/>                      <button x:name= "Minwinbutton"  grid.column= "2"  Style= "{ Staticresource winminbtnstyle} "                                            verticalcontentalignment= "Center"                                              Horizontalcontentalignment= "Center" >                          <Button.Content>                               <StackPanel>                                   <path stroke= "White"  strokethickness= "2"  data= "m1,6 l18,6"/>                               </StackPanel>                          </button.content >                      </Button>                      <button x:name= "Closewinbutton"  Grid.Column= "3"  style= "{Staticresource winclosebtnstyle}"  margin= "2,0,8,0"                                             horizontalcontentalignment= " Center "                                            verticalcontentalignment= "Center" >                           <Button.Content>                              <StackPanel>                                   <path stroke= "White"  StrokeThickness= "2"  data= "m2,2 l16,16 m2,16 l16,2"/>                               </StackPanel>                          </Button.Content>                      </button >                 </grid >                 < adornerdecorator grid.row= "1" >                      <contentpresenter/>                  </AdornerDecorator>              </Grid>              <Border.Effect>                  <DropShadowEffect/>              </Border.Effect>         </Border>      </ControlTemplate>     <style x:key= "Metrowindowstyle"  targettype= "{x: Type window} ">         <setter property=" Snapstodevicepixels " value=" True "/>         <Setter  Property= "OverridesdefaultstYle " value=" True "/>         <setter property=" AllowsTransparency " value=" True "/>         <Setter  Property= "Background"  value= "Transparent"/>         <setter  property= "WindowStyle"  value= "None"/>         <setter  property= "Template"  value= "{staticresource metrowindowtemplate}"/>      </Style> </ResourceDictionary>


Create a new Modernwindow class

C #

Public class modernwindow : window {    private Button 
CloseButton;
    private Button MinButton;
    private TextBlock WindowTitleTbl;     public modernwindow ()     {         this.
loaded += modernwindow_loaded; &NBSP;&NBSP;&NBSP;&NBSP}     private void modernwindow_loaded (Object sender ,  routedeventargs e)     {        //   Find form templates         controltemplate metrowindowtemplate                  = 
app.current.resources["Metrowindowtemplate"] as controltemplate;         if  (metrowindowtemplate != null)         {             closebutton = metrowindowtemplate.findname ("CloseWinButton",  this)
 as Button;             MinButton = 
Metrowindowtemplate.findname ("Minwinbutton",  this)  as Button;             CloseButton.Click += 
Closebutton_click;             minbutton.click += minbutton
_click;             WindowTitleTbl = 
Metrowindowtemplate.findname ("Windowtitletbl",  this)  as TextBlock;         }     }     private  void closebutton_click (object sender, systeM.windows.routedeventargs e)     {        
Close (); &NBSP;&NBSP;&NBSP;&NBSP}     private void minbutton_click (Object sender,  system.windows.routedeventargs e)     {         this.
windowstate = system.windows.windowstate.minimized;     }     /// <summary>     ///  Implement form Move     /// </summary>     /// <param name= "E "></param>     protected override void onmouseleftbuttondown ( Mousebuttoneventargs e)     {        dragmove (
);         base.
Onmouseleftbuttondown (e); &NBSP;&NBSP;&NBSP;&NBSP}}


Now that we've completed the Metro style form, we're going to apply it now. See MainWindow implementation:
XAML:

<local:modernwindow x:class= "Metrowindow.mainwindow"          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:metrowindow"         style= "{ Staticresource metrowindowstyle} "        mc:ignorable=" D "  "MainWindow"  height= "       title="  width= "525" >      <Grid>              </ Grid> </local:moderNwindow> 


C#:

public partial class Mainwindow:modernwindow
{public
MainWindow ()
{
InitializeComponent    ();
}
}



Now you're done with the Metro style form.


Since the release of Win8, more and more desktop applications have been implemented in metro style. There are also many WPF Metroui libraries, such as: http://mui.codeplex.com/. We can choose the existing Metro Ui/control according to the actual situation of the project, and of course we can write it ourselves.



WPF: Customize the Metro Style Folder selection dialog box FolderBrowserDialog


WPF does not have a File selection dialog box, and only controls that use the WinForm version are used. So far I haven't found a WPF version of the File selection dialog box.

May be my eyes muddy, if you know that there is a more robust version of the WPF Edition File Selection dialog box, File Open dialog box, please also leave a message.

This is a thin version of the File selection dialog box. Contains a UserControl and a window that hosts UserControl.

In addition, the TreeView style refers to the style from the Mahspps. That is, if you need to use this File selection dialog box, you must refer to Mahapps's associated DLL.

Of course, I will provide the source code for the entire project. If you don't mind, you can remove the Mahspps related references in your project. Of course, doing this may make the control interface look ugly, but you can also provide the TreeView with the style you like.

This file selection dialog is more streamlined, providing only the function of folder selection. Other features such as right-click menus, new folders, folder drag-and-drop are not currently implemented. To fully use WPF to achieve the full version of Microsoft FolderBrowserDialog, I believe that the workload is still quite large.

Start analysis

First open the WinForm version of the File selection dialog box to see what it looks like:


As you can see, from top to bottom: desktop (not expandable), library, computer (expand is each disk drive), network, Control Panel, Recycle Bin, and various folders on the desktop.

Regardless of Microsoft's custom design, the user is now accustomed to the design. Therefore, this implementation of the WPF version of the File selection dialog box is also generally used in this design. A few of them are:

The library is used too little to get rid of it.

Network This seems to have some to enter the password, I do not have a remote shared host, so it is not clear how Microsoft this is how to let users enter the password. Temporarily not implemented.

As for the control suites and Recycle Bin, I don't know what Microsoft meant by putting these two in the File Selection dialog box. Active Atmosphere ~ ~ ~

Actually here, I have an idea. Microsoft's File Selection dialog box in the way the operation of the file (including the right menu, file drag and drop, etc.) and the system's resource manager is very similar. So I suspect this file selection dialog box

The tree inside is actually embedded in an alternative resource manager, not a single tree developed by Microsoft ... In this way, it can also explain why Microsoft does not provide a WPF version of the File selection dialog box, because the Explorer internal implementation may not be implemented in the WPF approach, so the change is very heavy ... And then it's not available.

Of course, these are guesses, guesses.

Well, then again, the most important thing about this control is how to load the entire disk file through a tree, and then organize the entire disk file into a tree when you can't initialize it. The reasons for efficiency will never allow you to do that.

Is there a way to initialize a node when a user expands its child nodes?

Microsoft provides a template for the TreeView: Hierarchicaldatatemplate

With this template, when the user expands a node, the TreeView expands the node and initializes the child nodes of the node's child nodes, i.e. the first and second layers are initialized when the hierarchicaldatatemplate is first initialized. When the user expands the first layer, it begins to initialize the third layer ... by analogy. Because using this template to initialize the TreeView efficiency is quite impressive.

Here, we prepare a model for the TreeView:

This model should have at least a few attributes:

1.Name, the name of the node

2.FullName, the full disk path to the location of the node

3.Children, all child nodes of the node

In addition, you can continue to add if you need other similar icons.

In this example, model is as follows:



As you can see, there is one more type, which refers mainly to the type of node, such as the network, library, control Panel, etc. mentioned above, which says that they are folders but not so, so there is no way to deal with the same as the folder.

So give each node a type, not only easy to handle, but also convenient for later expansion.

The type is implemented as follows:

<summary>
///File Item type
///</summary>
internal enum Metrofolderbrowsercontrolmodeltype
{
///<summary>
///indicates that this is a folder
///</summary>
Directory,
///<s ummary>
///Desktop
///</summary>
Desktop,
///<summary>
///Computer 
  ///</summary>
Computer,
///<summary>
///disk drives///
</SUMMARY&G    t;
Disk,
}


Considering the different types of nodes that give them different node icons look better, so do:

 <summary>///  file Item type/// </summary> Public metrofolderbrowsercontrolmodeltype  type {    get     {       
 return type; &NBSP;&NBSP;&NBSP;&NBSP}     set     {         switch (value)         {             case metrofolderbrowsercontrolmodeltype.directory:                  {                     itemimagepath  = ImagePathHelper.FolderIconPath;            
          break;                 }              case metrofolderbrowsercontrolmodeltype.computer:                  {                     itemimagepath =  ImagePathHelper.ComputerIconPath;            
          break;                 }              case  Metrofolderbrowsercontrolmodeltype.desktop:                  {&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&Nbsp;        itemimagepath = imagepathhelper.desktopiconpath;                    
   break;                 }   
          case metrofolderbrowsercontrolmodeltype.disk:                 {                     
itemimagepath = imagepathhelper.diskiconpath;                   
  break;                 }              default:                  {             
       ItemImagePath = ImagePathHelper.FolderIconPath;                    
  break;                 }   
      }         type = value; &NBSP;&NBSP;&NBSP;&NBSP}}


The main thing now is that the implementation of the children is not done yet. How the children is implemented also affects the efficiency of the entire control.

for different types, use a different approach to get their children:

 <summary>///  subdirectory (file  +  folder)/// </summary> public  Observablecollection<metrofolderbrowsercontrolmodel> children {    get      {        try          {            if  (children !=  null)             {    
            return children;             }              children = new ObservableCollection<
Metrofolderbrowsercontrolmodel> ();             switch (Type)              {                 case metrofolderbrowsercontrolmodeltype.desktop:                      {                        
 break;                      }                  Case metrofolderbrowsercontrolmodeltype.computer:                      {                         foreach  (Var device in environment.getlogicaldrives ())                          {                              if  (directory.exists (device))                               {                               
  metrofolderbrowsercontrolmodel model = new metrofolderbrowsercontrolmodel ();                       &nbsP;          model.
filename = device;                                  model.
fullname = device;                                  model.
type = metrofolderbrowsercontrolmodeltype.disk;                                  children.
Invokeadd<metrofolderbrowsercontrolmodel> (model);                              }                          }             
            break;                      }                  Case metrofolderbrowsercontrolmodeltype.disk:                  case metrofolderbrowsercontrolmodeltype.directory:                      {                          foreach&nBSP; (Var item in explorerhelper.getdirectorychildrenitems (Fullname, true, false,  false))                          {                             
Metrofolderbrowsercontrolmodel model = new metrofolderbrowsercontrolmodel ();                              model. Filename = item.
Name;                              model. Fullname = item.
FullName;                              children.
ADD (model);                          }             
            break;                      }                  Default:                      {               
         break;                     }              }             return 
Children &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP}         catch  ( Exception)         {             //an exception, returns an empty collection             
return null;         }    &nbsp}}


Next use   bind, the tree is almost on display:

<treeview itemssource= "{binding metrofolderbrowsercontrolmodels}"  x:name= "TreeView" >     <TreeView.ItemTemplate>         < Hierarchicaldatatemplate itemssource= "{Binding children}" >              <stackpanel orientation= "Horizontal" >                  <image source= "{Binding  Itemimagepath, mode=twoway} " width="  height= "/>"                  <textblock text= "{Binding FileName}"  margin= "5,0,0,0"/>             </ Stackpanel>         </HierarchicalDataTemplate>      </treeview.itemtEmplate> </TreeView> 

        
The approximate effect is as follows:


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.