国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C# > 正文

C#中WPF依賴屬性的正確學習方法

2020-01-24 00:01:50
字體:
來源:轉載
供稿:網友

前言

我在學習WPF的早期,對依賴屬性理解一直都非常的不到位,其惡果就是,我每次在寫依賴屬性的時候,需要翻過去的代碼來復制黏貼。

相信很多朋友有著和我相同的經歷,所以這篇文章希望能幫助到那些剛剛開始學依賴屬性的朋友。

那些[討厭]的依賴屬性的講解文章

初學者肯定會面臨一件事,就是百度,谷歌,或者MSDN來查看依賴屬性的定義和使用,而這些文章雖然都寫的很好,但,那是相對于已經學會使用依賴屬性的朋友而言。

而對于初學者而言,說是誤導都不過分。

比如,官網的這篇文章https://docs.microsoft.com/zh-cn/dotnet/framework/wpf/advanced/dependency-properties-overview

介紹依賴屬性是這樣。

public static readonly DependencyProperty IsSpinningProperty =  DependencyProperty.Register(  "IsSpinning", typeof(Boolean),  typeof(MyCode)  );public bool IsSpinning{  get { return (bool)GetValue(IsSpinningProperty); }  set { SetValue(IsSpinningProperty, value); }}

他做了一個定義,然后告訴你,依賴屬性的定義格式如此。

如果你是個初學者,你想不疑惑都很難。因為沒人能把這種定義給背下來。

其結果就是,你要和我當初一樣,每次定義依賴屬性,都要去復制黏貼。但這并不是最大的惡果,最大的惡果是,因為太過復雜的定義,讓你放棄了對他理解,就記住了依賴屬性要復制黏貼,從而導致了,你喪失了對依賴屬性靈活運用的能力。

正確的理解依賴屬性

如何正確的理解依賴屬性呢?

很簡單,拆分一下就可以理解了。

現在我們來拆分依賴屬性,首先拆分他的定義,將依賴和屬性拆分。

我們先看屬性,如下,我們定義了一個屬性。

private bool _IsSpinning;public bool IsSpinning{  get { return _IsSpinning; }  set { _IsSpinning = value; }}

然后我們使用DependencyProperty類定義一個對象,這個對象將作為IsSpinning屬性的依賴,如下:

public static readonly DependencyProperty IsSpinningProperty

然后,我們在將這個依賴對象,注冊到屬性IsSpinning的所在類上,如下:

DependencyProperty.Register( "IsSpinning", typeof(bool), typeof(你的屬性所在的類的名稱));

從注冊代碼中,我們可以看到,他注冊了三個信息:

1,當前DependencyProperty類定義的對象IsSpinningProperty,依賴于屬性IsSpinning。

2,對象IsSpinningProperty的依賴類型與屬性IsSpinning的類型一樣都是bool。

3,對象IsSpinningProperty注冊的類是聲明屬性IsSpinning的類,即,在其他類里,將看不到該依賴對象。

現在,我們做最后的操作,修改屬性,將依賴對象IsSpinningProperty與屬性IsSpinning綁定。

如何綁定呢?很簡單,將我們屬性定義里的【private bool _IsSpinning】替換為我們剛剛定義的依賴【IsSpinningProperty】即可。

public bool IsSpinning{  get { return (bool)GetValue(IsSpinningProperty); }  set { SetValue(IsSpinningProperty, value); }}

這里我們看到了,在給屬性賦值和取值時,用到了GetValue和SetValue,他們倆是哪來的呢?

使用F12,我們跟蹤進去,發現它們是類DependencyProperty里定義的方法,那么為什么我們在窗體里也可以用呢?

很簡單,我們跟進一下Window的父類,發現最后的父類Visual繼承了DependencyProperty,所以我們可以直接使用GetValue和SetValue來賦值和獲取依賴對象的值。也就是只要是繼承了類DependencyProperty的子類,都可以使用依賴屬性。

完整版依賴屬性定義代碼:

public static readonly DependencyProperty IsSpinningProperty =DependencyProperty.Register("IsSpinning", typeof(bool), typeof(DependecyUserControl));public bool IsSpinning{  get { return (bool)GetValue(IsSpinningProperty); }  set { SetValue(IsSpinningProperty, value); }}

到這里,依賴屬性的拆分就完事了,現在,大家應該很清楚依賴屬性到底是什么了吧。

現在你已經理解這些依賴屬性的概念了,只要熟練一點點,實現手敲依賴屬性已經不是夢了。

PS:有沒有人曾經告訴你,依賴屬性的命名必須是 屬性名+Property,然后你還信以為真了。哈哈。

依賴屬性的簡單應用

現在讓我們來自定義一個帶依賴屬性的系統控件來加深記憶。

public class KButton : Button {  public static readonly DependencyProperty ForeImageProperty;  public static readonly DependencyProperty BackImageProperty;  public static readonly DependencyProperty MouseOverBackColorProperty;  public static readonly DependencyProperty StretchProperty;   static KButton()  {    ForeImageProperty = DependencyProperty.Register("ForeImage", typeof(string), typeof(KButton),null);    ForeImageProperty = DependencyProperty.Register("BackImage", typeof(string), typeof(KButton),null);    MouseOverBackColorProperty = DependencyProperty.Register("MouseOverBackColor", typeof(Brush), typeof(KButton), null);    StretchProperty = DependencyProperty.Register("Stretch", typeof(Stretch), typeof(KButton), null);    DefaultStyleKeyProperty.OverrideMetadata(typeof(KButton), new FrameworkPropertyMetadata(typeof(KButton)));//使KButton去讀取KButton類型的樣式,而不是去讀取Button的樣式  }  public string ForeImage  {    get { return (string)GetValue(ForeImageProperty); }    set { SetValue(ForeImageProperty, value); }  }  public string BackImage  {    get { return (string)GetValue(BackImageProperty); }    set { SetValue(BackImageProperty, value); }  }  public Brush MouseOverBackColor  {    get { return (Brush)GetValue(MouseOverBackColorProperty); }    set { SetValue(MouseOverBackColorProperty, value); }  }  public Stretch Stretch  {    get { return (Stretch)GetValue(StretchProperty); }    set { SetValue(StretchProperty, value); }  } }

如上述代碼所示,我們定義了一個繼承至Button的類KButton。

在KButtion中,我們定義了四個依賴屬性:

ForeImageProperty:按鈕的前景圖片。

BackImageProperty:按鈕的背景圖片。

MouseOverBackColorProperty:按鈕在鼠標經過時的顏色。

StretchProperty:按鈕圖片的拉伸模式。

代碼非常簡潔,除了四個依賴屬性之外,什么也沒有;現在我們去定義Kbutton類型的樣式。

為了演示方便,我直接將樣式定義在了App.xaml文件內。

<Style TargetType="{x:Type local:KButton}">  <Setter Property="Template">    <Setter.Value>      <ControlTemplate>        <DockPanel Name="dpCon" Width="{Binding Width, RelativeSource={x:Static RelativeSource.TemplatedParent}}"            Height="{Binding Height, RelativeSource={x:Static RelativeSource.TemplatedParent}}"            Background="{Binding Background, RelativeSource={x:Static RelativeSource.TemplatedParent}}"            ToolTip="{Binding ToolTip, RelativeSource={x:Static RelativeSource.TemplatedParent}}"            >          <DockPanel DockPanel.Dock="Top" Name="dpBtn">            <DockPanel.Background>              <ImageBrush ImageSource="{Binding ForeImage, RelativeSource={x:Static RelativeSource.TemplatedParent}}" Stretch="{Binding Stretch,RelativeSource={x:Static RelativeSource.TemplatedParent}}"/>            </DockPanel.Background>            <TextBlock FontSize="15" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="#f9fcff" Text="{Binding Content, RelativeSource={x:Static RelativeSource.TemplatedParent}}"></TextBlock>          </DockPanel>        </DockPanel>        <ControlTemplate.Triggers>           <DataTrigger Binding="{Binding IsMouseOver,RelativeSource={x:Static RelativeSource.Self}}" Value="True">            <Setter Property="Background" TargetName="dpBtn">              <Setter.Value>                <ImageBrush ImageSource="{Binding BackImage, RelativeSource={x:Static RelativeSource.TemplatedParent}}" Stretch="{Binding Stretch,RelativeSource={x:Static RelativeSource.TemplatedParent}}"/>              </Setter.Value>            </Setter>            <Setter Property="Background" TargetName="dpCon" Value="{Binding MouseOverBackColor, RelativeSource={x:Static RelativeSource.TemplatedParent}}"></Setter>          </DataTrigger>          <DataTrigger Binding="{Binding BackImage,RelativeSource={x:Static RelativeSource.Self},Mode=TwoWay}" Value="{x:Null}">            <Setter Property="Background" TargetName="dpBtn">              <Setter.Value>                <ImageBrush ImageSource="{Binding ForeImage, RelativeSource={x:Static RelativeSource.TemplatedParent}}" Stretch="{Binding Stretch,RelativeSource={x:Static RelativeSource.TemplatedParent}}"/>              </Setter.Value>            </Setter>           </DataTrigger>          <Trigger Property="IsEnabled" Value="true"/>          <Trigger Property="IsEnabled" Value="false">            <Setter Property="Foreground" Value="Gray"/>          </Trigger>        </ControlTemplate.Triggers>      </ControlTemplate>    </Setter.Value>  </Setter></Style>

樣式代碼如上所示,也非常簡單,就是定義了一個模板,然后在模板里擺放好按鈕背景圖和按鈕文字的位置。然后將我們之前定義好的依賴屬性綁定到對應的值上。

其中需要注意的是,在模板中綁定自定義依賴屬性,是使用RelativeSource.TemplatedParent的,如

{Binding ForeImage,

RelativeSource={x:Static RelativeSource.TemplatedParent}}。

而在模板的數據事件DataTrigger中,綁定依賴屬性的模式卻是分兩種的。

第一種,綁定數據事件DataTrigger的條件時,使用RelativeSource.Self,如{Binding IsMouseOver,RelativeSource={x:Static RelativeSource.Self}}。

第二種,條件成立,觸發模板變化時,使用RelativeSource.TemplatedParent,如{Binding BackImage, RelativeSource={x:Static RelativeSource.TemplatedParent}}

----------------------------------------------------------------------------------------------------

現在我們使用下我們制作好的自定義控件,代碼如下所示:

<DockPanel>  <StackPanel>    <local:KButton Height="50" Width="50" Stretch="None" ForeImage="/Image/關閉.png" BackImage="/Image/關閉退出.png" Background="Gray" MouseOverBackColor="Brown"/>    <local:KButton Height="50" Width="50" Margin="0,10,0,0" Stretch="None" ForeImage="/Image/關閉.png" Background="Gray" MouseOverBackColor="Brown"/>    <local:KButton Height="100" Width="100" Margin="0,10,0,0" Content="籃子" Stretch="Fill" ForeImage="/Image/籃子.png" Background="Gray" MouseOverBackColor="Brown"/>  </StackPanel> </DockPanel>

界面效果如下:

自定義用戶控件中使用依賴屬性

首先我們添加新項,然后選擇用戶控件。

然后,我們添加一個依賴屬性HeaderTitle,同時設置當前控件的DataContext為自身―this.DataContext = this。

public string HeaderTitle{  get { return (string)GetValue(HeaderTitleProperty); }  set { SetValue(HeaderTitleProperty, value); }} public static readonly DependencyProperty HeaderTitleProperty = DependencyProperty.Register("HeaderTitle", typeof(string), typeof(DependecyUserControl), null); public DependecyUserControl(){  this.DataContext = this;  InitializeComponent();}

現在,我們在用戶控件的Xaml頁面添加一個TextBlock,并綁定他的Text為我們剛剛定義的HeaderTitle,代碼如下所示。

<Grid>  <TextBlock Text = "{Binding HeaderTitle}" TextAlignment="Center"></TextBlock></Grid>

接著我們回到主窗體,引用這個用戶控件,代碼如下所示:

<local:DependecyUserControl Height = "30" HeaderTitle="我是Header" DockPanel.Dock="Top"></local:DependecyUserControl>

運行結果:

可以看到,我們成功在主頁面設置了用戶控件的依賴屬性,并讓他成功的綁定到了用戶控件中的TextBlock的Text屬性。也就是說,我們簡單的實現了Header的Title動態設置。

結語

WPF擁有非常強大的自定義能力,而,正確的學會了依賴屬性是體會到它強大的第一步。

----------------------------------------------------------------------------------------------------

到此WPF依賴屬性的正確學習方法就已經講解完成了。

代碼已經傳到Github上了,歡迎大家下載。

Github地址:https://github.com/kiba518/WpfDependency

總結

以上所述是小編給大家介紹的C#中WPF依賴屬性的正確學習方法,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對武林網網站的支持!
如果你覺得本文對你有幫助,歡迎轉載,煩請注明出處,謝謝!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 碌曲县| 金川县| 瓮安县| 潼关县| 仙居县| 铁岭市| 化州市| 霞浦县| 怀柔区| 泾川县| 德清县| 宝鸡市| 扶绥县| 时尚| 鄂托克前旗| 阳信县| 皋兰县| 固始县| 随州市| 镇远县| 海口市| 土默特左旗| 郧西县| 南平市| 鄂托克前旗| 治县。| 巴林左旗| 沙湾县| 东阿县| 营山县| 武川县| 龙游县| 冕宁县| 女性| 绥德县| 依兰县| 广西| 红安县| 阿拉善左旗| 义马市| 顺平县|