乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      WPF 原生綁定和命令功能使用指南

       小樣樣樣樣樣樣 2021-04-14

      魏劉宏 2020 年 2 月 21 日

      如今,當(dāng)談到 WPF 時,我們言必稱 MVVM、框架(如 Prism)等,似乎已經(jīng)忘了不用這些的話該怎么使用 WPF 了。當(dāng)然,這里說的不用框架和 MVVM,并不是說像使用 Winform 那樣使用 WPF,而是追本溯源,重識 WPF 與生俱來的綁定命令的風(fēng)采。

      一、綁定的使用

      目標(biāo):前臺頁面通過綁定獲取后臺屬性的值。

      這個目標(biāo)實際上分為兩部分,一是前臺獲取后臺的屬性值,二是屬性值變動后能夠及時體現(xiàn)出來。

      要實現(xiàn)目標(biāo)的第一部分,實際只需在窗體后臺的構(gòu)造函數(shù)中添加一行代碼即可:

      this.DataContext = this;

      這行代碼很關(guān)鍵,MVVM 模式中頁面與 ViewModel 關(guān)聯(lián)也是通過指定頁面類的 DataContext 為相應(yīng)的 ViewModel 對象來實現(xiàn)的。

      下面再來說說如何實現(xiàn)目標(biāo)的第二部分,也就是屬性變化后能及時體現(xiàn)出來,包括后臺屬性變化后前臺顯示自動變化,以及前臺修改了內(nèi)容,后臺屬性的值跟著改變。眾所周知,這就是綁定,而要實現(xiàn)這一功能,需要相關(guān)類實現(xiàn)一個屬性變動通知接口 —— InotifyPropertyChanged 。具體演變過程可參考網(wǎng)上的文章《 .NET 4.5 (C#):INotifyPropertyChanged 執(zhí)行的演變:從表達(dá)式樹到調(diào)用方信息的 BindableBase 類型 | Mgen》,這里直接給出最后的結(jié)果。

      首先,實現(xiàn) InotifyPropertyChanged 當(dāng)然是必要的,如果是要綁定其他類,則讓該類實現(xiàn)之,如果是直接在窗口后臺做相關(guān)功能,則最終窗口類看上去像這樣:

      public partial class MainWindow : Window, INotifyPropertyChanged

      然后添加一個事件和兩個方法:

      public event PropertyChangedEventHandler PropertyChanged; 
      protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
      {var eventHandler = this.PropertyChanged;
          eventHandler?.Invoke(this, new PropertyChangedEventArgs(propertyName));
      } 
      protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] String propertyName = null)
      {if (Equals(storage, value)) return false;
       
          storage = value;this.OnPropertyChanged(propertyName);return true;
      }

      最后就是要提供綁定的屬性了,可以像下面這樣寫:

      private string _UserName = "wlh";public string UserName
      {get => _UserName;set => SetProperty(ref _UserName, value);
      }

      前臺綁定就很簡單了:

      <TextBox Text="{Binding UserName, Mode=TwoWay}"></TextBox>

      二、命令 ICommand

      WPF 和 Winform 的重大區(qū)別就是,用戶的交互、數(shù)據(jù)的變化等,在 Winform 中,都需要程序員一點一點仔細(xì)地手動處理,而在 WPF 中,數(shù)據(jù)是綁定的,交互通過命令傳遞,所以很多事情其實 WPF 這個大框架就可以幫我們自動處理了。說了這么多,其實就是說 Winform 是事件驅(qū)動的,而 WPF 是數(shù)據(jù)驅(qū)動的,所以在 Winform 中常用的按鈕點擊事件等各種事件,在 WPF 中是不怎么用了,而是使用命令。

      命令也是綁定的,先來看看前臺的樣子:

      <TextBox Text="{Binding UserName, Mode=TwoWay}"></TextBox>

      至于后臺怎么寫,先不急,通過《[WPF] ICommand 最佳使用方法》一文,我們知道首先需要一個輔助類:

      public class RelayCommand : ICommand
      {private readonly Predicate<object> _CanExecute;private readonly Action<object> _Execute; public RelayCommand(Predicate<object> canExecute, Action<object> execute)
          {this._CanExecute = canExecute;this._Execute = execute;
          } public event EventHandler CanExecuteChanged
          {
              add => CommandManager.RequerySuggested += value;
              remove => CommandManager.RequerySuggested -= value;
          } public bool CanExecute(object parameter)
          {return _CanExecute(parameter);
          } public void Execute(object parameter)
          {
              _Execute(parameter);
          }
      }

      可見 ICommand 中主要有兩個方法,一個檢查命令是否可用的 CanExecute (),以及實際干活的 Execute () 。

      然后在后臺添加一個 “DoSomething” 的命令,也就是上面新建的 RelayCommand 類型:

      private ICommand _DoSomething;public ICommand DoSomethingCommand
      {get{return _DoSomething ??= new RelayCommand(
                  o => _CanDoSomething(o),
                  o => { _DoSomethingMethod(o); });
          }
      } 
      private readonly Predicate<object> _CanDoSomething = o => true; 
      // 可在之后再賦值,避免方法體中訪問屬性等受阻;private readonly Action<object> _DoSomethingMethod = o =>{// do something};

      這些還可以進(jìn)一步簡化為:

      public ICommand DoSomethingCommand { get; set; } 
      /// <summary>/// 命令方法賦值(在構(gòu)造方法中調(diào)用)/// </summary>private void SetCommandMethod()
      {
          DoSomethingCommand ??= new RelayCommand(o => true, async o =>{// do something    });
      }

      最后來看看對應(yīng)前臺”GetTokenCommand” 命令的實際業(yè)務(wù)代碼:

      public ICommand GetTokenCommand { get; set; } 
      /// <summary>/// 命令方法賦值 (在構(gòu)造函數(shù)中調(diào)用)/// </summary>private void SetCommandMethod()
      {
          GetTokenCommand ??= new RelayCommand(o => !(string.IsNullOrEmpty(UserName) || string.IsNullOrEmpty(Password)), async o =>{var req = new ReqGetToken()
              {
                  userName = UserName,
                  password = Password,
              }; var res = await GetToken(req);if (res.Code)
              {
                  Token = res.Token;
              }
          });
      }

      可以看到,在檢查命令是否可用的部分,沒有像樣板代碼那樣直接返回 true ,而是按照實際情況判斷,這樣的效果就是,當(dāng)條件不滿足時,前臺相關(guān)控件自動禁用:

       

      最后,經(jīng)過我們這樣寫,其實和 MVVM 模式已經(jīng)很接近了,只要把后臺所有代碼都移到另一個類,然后將頁面的 DataContext 重新指定一下,就能實現(xiàn)頁面顯示和業(yè)務(wù)邏輯分離了。

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多