C# 值得永久收藏的WPF項目實戰(經典)


01

 

 

簡介

 

之前也寫過好多篇CM框架相關的項目實戰文章,比如:

C# WPF框架Caliburn.Micro快速搭建

C# WPF框架Caliburn.Micro入門實例1

C# WPF MVVM項目實戰(進階①)

C# WPF MVVM項目實戰(進階②)

C# WPF MVVM模式下在主窗體顯示子窗體並獲取結果

C# WPF Caliburn.Micro框架下利用Mef加載其它項目界面

C# WPF mvvm模式下combobox綁定(list<enum>、Dictionary<int,string>)

C# WPF MVVM模式Caliburn.Micro框架下事件發布與訂閱

但是可能這些都是把一個綜合性的項目分多個部分分別講述的,有些初學者沒有從前往后連續起來閱讀的話,后面的部分可能就不容易理解了。其次,因為沒有整體的構思,隨着內容的增加,項目越來越顯得笨重和凌亂,所以今天我重新搞了一個項目,希望以盡量少的代碼,涵蓋盡量多的知識點,幫助大家更好的理解和使用CM框架。

02

 

重要知識點

 

  • CM框架的配置和啟動;

  • CM框架自帶ioc容器SimpleContainer用法;

  • MVVM開發模式;

  • 事件聚合器EventAggregator進行事件發布和訂閱;

  • 屬性通知:

    ① CM框架下基類PropertyChangedBase用法;

    ②PropertyChanged.Fody.3.1.3下 [AddINotifyPropertyChangedInterface]用法;

  • 日志框架:Common.Logging和log4net用法;

  • CM框架下命名約定以及事件關聯;

  • 用第三方庫Xceed.Wpf.Toolkit.dll做等待窗體;

  • CM框架下Conductor用法;

  • CM框架下IWindowManager;

  • 雙檢鎖單例模式用法;

  •  ListBox數據綁定以及窗體切換;

    如果以上知識點你都不敢興趣或者已經熟知,那這篇文章不適合你,看到這里你就可以關閉網頁了!

     

03

 

運行結果

 

 

 

04

 

項目說明

 

項目主要包括的類文件如下圖:

 

 

 

① MainWindowViewModel.cs類:

using PropertyChanged;
using System.Collections.ObjectModel;
​
namespace Caliburn.Micro.Hello
{
    [AddINotifyPropertyChangedInterface]
    public class MainWindowViewModel : PropertyChangedBase, IViewModel
    {
        private static readonly Common.Logging.ILog logger = Common.Logging.LogManager.GetLogger<MainWindowViewModel>();
        public IViewModel ActiveWindowView { get; set; }
        public ObservableCollection<string> ListBoxItems { get; set; } 
        public string SelectedItem { get; set; }
        public MainWindowViewModel()
        {
            logger.Info($"Enter [MainWindowViewModel].");
            ListBoxItems = new ObservableCollection<string>() { };
            ListBoxItems.Add("ShellView");
            ListBoxItems.Add("EventAggregatorView");
            ListBoxItems.Add("ConductorView");
            logger.Info($"Leave [MainWindowViewModel].");
        }
        public void ListBoxItems_SelectionChanged()
        {
           switch(SelectedItem)
            {
                case "ShellView":
                    ActiveWindowView = new ShellViewModel();break;
                case "EventAggregatorView":
                        ActiveWindowView = EventAggregatorViewModel.Instance; break;
                case "ConductorView":
                    ActiveWindowView = new ConductorViewModel(); break;
                default:break;
            }
        }
    }
}
​

  

  • [AddINotifyPropertyChangedInterface]:需要引用第三方庫PropertyChanged.Fody,加上之后類里面的屬性變更后會自動通知界面,無需再一個個單獨觸發;

  • logger是定義的common logging的一個通用日志,需要在nuget上引用:Common.Logging.Log4Net1213;

  • ListBoxItems_SelectionChanged()是listbox的選擇改變事件:

    需要在前台附加事件:

  • <ListBox Name="ListBoxItems" Grid.Column="0" SelectedItem="{Binding SelectedItem}" Margin="2"
    cal:Message.Attach="[Event SelectionChanged] = [Action ListBoxItems_SelectionChanged]"/>
    

      ActiveWindowView 是我的主窗體,選擇那個就激活那個

  •  <ContentControl Name="ActiveWindowView"/>
    

      

    ②ShellViewModel.cs類:

    從ioc容器獲取一個IWindowManager並顯示:

  • SimpleContainerViewModel simpleContainerViewModel = new SimpleContainerViewModel();
      IWindowManager windowManager = IoC.Get<IWindowManager>();
       windowManager.ShowDialog(simpleContainerViewModel);
    

      CanSayHello和SayHello,只有CanSayHello條件滿足才會執行SayHello

  •  public bool CanSayHello
            {
                get { return !string.IsNullOrWhiteSpace(Name); }
            }
    ​
            public void SayHello()
            {  
            }
    

      

    ③EventAggregatorViewModel.cs

    雙檢鎖線程安全的單例模式:

  • private static EventAggregatorViewModel instance;
            private static object locker = new object();
            /// <summary>
            /// 雙檢鎖
            /// </summary>
            public static EventAggregatorViewModel Instance
            {
                get
                {
                    if (instance == null)
                    {
                        lock(locker)
                        {
                            if (instance == null)
                            {
                                instance = new EventAggregatorViewModel();
                            }
                        }
                    }
                    return instance;
                }
            }
    

      事件訂閱:需要繼承事件接口IHandle<PersonInfoEven>

  •  private readonly IEventAggregator eventAggregator;
     this.eventAggregator = IoC.Get<IEventAggregator>(); 
     this.eventAggregator.Subscribe(this);
    

      事件處理方法:

  •  public void Handle(PersonInfoEven message)
            {
                PersonInfo = message.ToString();
            }
    

     

    ④SimpleContainerViewModel.cs

      方法1 同步ui發布事件

  • this.eventAggregator.PublishOnUIThread("i am a chinese");
    

       方法2 開線程去發布 

  •  this.eventAggregator.Publish(new PersonInfoEven() {
                    Name = "ZYR", Age = 18, Sex = "man" }, 
                    action =>
                {
                    //方式①
                    //Task.Factory.StartNew(action);
                    //方式②
                    Task.Run(action);
                });
    

      

    等待窗體BusyIndicator ,需要引用第三方庫Xceed.Wpf.Toolkit,

    並添加名稱空間:

    xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"

  • <xctk:BusyIndicator Name="busyIndicator"  BusyContent="Publish Event ..." IsBusy="{Binding IsShow}" Style="{x:Null}">
    

      

    ⑤ConductorViewModel.cs:此類需要繼承Conductor<object>

    將需要激活的實例放到ActivateItem,就可以從界面綁定激活對應實例窗體

    ActivateItem(new ShellViewModel());

     

    05

     

    源碼下載

    項目有點長,不可能每個細節都說得到位,能看到這里的都是真愛,那么下面給出源碼百度網盤鏈接:

  • 網盤鏈接:
    
    https://pan.baidu.com/s/18LOVAIxy7WCWJisiPcOuAQ
    
    提取碼:添加小編微信獲取
    
    小編微信:mm1552923
    
    公眾號:dotNet編程大全
    

      

     


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM