binding
RaisePropertyChanged
屬性改變事件
https://blog.csdn.net/cselmu9/article/details/8275255
?
?
INotification?通知
https://www.cnblogs.com/lonelyxmas/p/10669406.html
?
binding
<TextBox Name="textBox1" Text="{Binding Path=Value,ElementName=slider1}"/> <Slider HorizontalAlignment="Left" Margin="84,106,0,0" Name="slider1" VerticalAlignment="Top" />有的時(shí)候我們會(huì)在代碼中我們看大Path是一個(gè)“.”或者干脆沒有Path的Binding,著實(shí)讓人摸不著頭腦。原來這是一種比較特殊的情況---Binding源本身就是一種數(shù)據(jù)且不需要Path來指明。典型的string,int等基本類型都是這樣,他們是實(shí)例本身就是數(shù)據(jù),我們無法指定通過那個(gè)屬性來訪問這個(gè)數(shù)據(jù),這是我們只需要將這個(gè)數(shù)據(jù)設(shè)置為.就可以了。在XAML中這個(gè).可以忽略不寫,但是在C#中編程必須要帶上。
在使用集合類型的數(shù)據(jù)作為列表控件的ItemSource時(shí)一般會(huì)考慮使用ObservableCollection<T>替換List<T>,因?yàn)镺bservableCollection<T>類實(shí)現(xiàn)了INotifyChange和INotifyPropertyChanged接口,能把集合的變化立刻通知顯示到它的列表控件上,改變會(huì)立刻顯示出來。
?
?
單值轉(zhuǎn)換實(shí)例,IValueConverter
?
1.當(dāng)值從綁定源傳播給綁定目標(biāo)時(shí),調(diào)用方法Convert
2.當(dāng)值從綁定目標(biāo)傳播給綁定源時(shí),調(diào)用此方法ConvertBack,方法ConvertBack的實(shí)現(xiàn)必須是方法Convert的反向?qū)崿F(xiàn)。
/// <summary>/// 自定義事件轉(zhuǎn)換/// </summary>public class TimeConver : IValueConverter{//當(dāng)值從綁定源傳播給綁定目標(biāo)時(shí),調(diào)用方法Convertpublic object Convert(object value, Type targetType, object parameter, CultureInfo culture){if (value == null)return DependencyProperty.UnsetValue;DateTime date = (DateTime)value;return date.ToString("yyyy-MM-dd");}//當(dāng)值從綁定目標(biāo)傳播給綁定源時(shí),調(diào)用此方法ConvertBackpublic object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture){string str = value as string;DateTime txtDate;if (DateTime.TryParse(str, out txtDate)){return txtDate;}return DependencyProperty.UnsetValue;}}注:返回值DependencyProperty.UnsetValue表示轉(zhuǎn)換器沒有生成任何值。
在xaml中引用TimeConver的命名空間
xmlns:local="clr-namespace:AudioDemo.View"在xaml中定義Resources
<Window.Resources><local:TimeConver x:Key="cvtDate"/> </Window.Resources>在xaml重指定Binding值使用自定義Converter轉(zhuǎn)換
<Grid><DatePicker x:Name="dateOne" HorizontalAlignment="Left" Margin="85,50,0,0" VerticalAlignment="Top" Width="183"SelectedDateFormat="Long"/><TextBox x:Name="textBox" Text="{Binding ElementName=dateOne,Path=SelectedDate,Converter={StaticResource cvtDate}}" HorizontalAlignment="Left" Height="23" Margin="85,105,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="183"/><Label x:Name="label" Content="選擇結(jié)果:" HorizontalAlignment="Left" Margin="19,105,0,0" VerticalAlignment="Top"/><Label x:Name="label1" Content="{Binding ElementName=dateOne,Path=Text}" HorizontalAlignment="Left" Margin="85,145,0,0" VerticalAlignment="Top"/> </Grid> <TextBox x:Name="textBox" Text="{Binding ElementName=dateOne,Path=SelectedDate,Converter={StaticResource cvtDate}}" HorizontalAlignment="Left" Height="23" Margin="85,105,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="183"/> public class ColorConverter : IMultiValueConverter {//正向修改public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture){if (values == null || values.Length < 2)return DependencyProperty.UnsetValue;double verValue = (double)values[0];double horValue = (double)values[1];if (verValue > horValue)return new SolidColorBrush(Colors.Green);else if (verValue < horValue)return new SolidColorBrush(Colors.Red);return new SolidColorBrush(Colors.Yellow);}//反向修改public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture){//返回空,標(biāo)記不可雙向轉(zhuǎn)換return null;} }?
xmlns:local="clr-namespace:AudioDemo.View" <Window.Resources><local:ColorConverter x:Key="cvtColor"/> </Window.Resources> <Grid><Label x:Name="label" Content="縱向值:" HorizontalAlignment="Left" Margin="10,40,0,0" VerticalAlignment="Top"/><Label x:Name="label1" Content="橫向值:" HorizontalAlignment="Left" Margin="10,80,0,0" VerticalAlignment="Top"/><Slider x:Name="sliderVer" HorizontalAlignment="Left" Margin="75,43,0,0" VerticalAlignment="Top" Width="192"/><Slider x:Name="sliderHor" HorizontalAlignment="Left" Margin="75,81,0,0" VerticalAlignment="Top" Width="192"/><Ellipse HorizontalAlignment="Left" Height="100" Margin="75,120,0,0" Stroke="Black" VerticalAlignment="Top" Width="100"><Ellipse.Fill><MultiBinding Converter="{StaticResource cvtColor}"><Binding Path="Value" ElementName="sliderVer"/><Binding Path="Value" ElementName="sliderHor"/></MultiBinding></Ellipse.Fill></Ellipse> </Grid> public class RGBConverter : IMultiValueConverter {//正向修改,整合顏色值public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture){if (values == null || values.Length < 3)return null;byte r = System.Convert.ToByte(values[0]);byte g = System.Convert.ToByte(values[1]);byte b = System.Convert.ToByte(values[2]);Color col = Color.FromRgb(r, g, b);SolidColorBrush brush = new SolidColorBrush(col);return brush;}public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture){return null;} } xmlns:local="clr-namespace:AudioDemo.View" <Window.Resources><local:RGBConverter x:Key="rgbCvt"/> </Window.Resources> <Grid><Label x:Name="label" Content="Red:" HorizontalAlignment="Left" Margin="10,48,0,0" VerticalAlignment="Top"/><Label x:Name="label_Copy" Content="Green:" HorizontalAlignment="Left" Margin="7,85,0,0" VerticalAlignment="Top"/><Label x:Name="label_Copy1" Content="Blue:" HorizontalAlignment="Left" Margin="7,123,0,0" VerticalAlignment="Top"/><Slider x:Name="slider_r" Minimum="0" Maximum="255" Ticks="1" HorizontalAlignment="Left" Margin="68,53,0,0" VerticalAlignment="Top" Width="207"/><Slider x:Name="slider_g" Minimum="0" Maximum="255" Ticks="1" HorizontalAlignment="Left" Margin="68,91,0,0" VerticalAlignment="Top" Width="207"/><Slider x:Name="slider_b" Minimum="0" Maximum="255" Ticks="1" HorizontalAlignment="Left" Margin="68,124,0,0" VerticalAlignment="Top" Width="207"/><Rectangle HorizontalAlignment="Left" Height="90" Margin="68,160,0,0" Stroke="Black" VerticalAlignment="Top" Width="142"><Rectangle.Fill><MultiBinding Converter="{StaticResource rgbCvt}"><Binding ElementName="slider_r" Path="Value"></Binding><Binding ElementName="slider_g" Path="Value"></Binding><Binding ElementName="slider_b" Path="Value"></Binding></MultiBinding></Rectangle.Fill></Rectangle></Grid> <Button Content="Test"><Button.Background><MultiBinding Converter="{StaticResource mutiBoolConverter}"><Binding Path="IsEnableCredentialsAdded"/><Binding Path="IsOld"/></MultiBinding></Button.Background> </Button>?
<TextBox Height="20" Margin="0,0,10,87" Text="{Binding ElementName=slider1,Path=Value}" BorderThickness="1"/><Slider Maximum="100" Margin="0,50,0,35" Name="slider1"/>?
改善優(yōu)化WPF Binding
下面的內(nèi)容在修正錯(cuò)誤的同時(shí),還將對(duì)原有的Binding做一些小小的改進(jìn)。
?
情況如下:在將數(shù)據(jù)庫中的DataTable對(duì)象的DefaultView通過XAML語言Binding到listView1對(duì)象的ItemsSource上時(shí)總是失敗。
?
答案那就是使用DataContext,這里先來梳理一下Binding的一些基本概念及使用方法。
?
?
l?典型的Binding具有四個(gè)重要組成部分:Binding目標(biāo)對(duì)象(binding target object)、目標(biāo)對(duì)象屬性(target property)、Binding數(shù)據(jù)源(binding source)、Path(用于指明要從數(shù)據(jù)源中取得的值,就是我們通常寫的屬性名稱)。
?
?
例如:想要把一個(gè)員工(Employee)的姓名(EmpName)Binding顯示到一個(gè)TextBox的Text屬性上。
?
分析一下其中的4個(gè)組成部分:Binding目標(biāo)對(duì)象是TextBox(因?yàn)樗罱K使用這些數(shù)據(jù));目標(biāo)對(duì)象屬性是TextProperty(這里要注意,不是Text屬性,而是與Text屬性相對(duì)應(yīng)的Dependency Property,通常命名是屬性名+Property);
?
數(shù)據(jù)源是員工(Employee);Path是EmpName。我的經(jīng)驗(yàn)是:剛開始使用Binding的時(shí)候由于還不熟悉,建議在做之前先在心理把這4個(gè)部分對(duì)號(hào)入座一下,等日后就可以熟悉成自然了。
?
l?目標(biāo)對(duì)象屬性一定要是Dependency Property。由于只有DependencyObject類及其子類能夠定義Dependency Property,因此,Binding目標(biāo)對(duì)象就必須是DependencyObject類及其子類了。另一方面反過來說,UIElement(DependencyObject的子類)的大多數(shù)屬性都有與其對(duì)應(yīng)的Dependency Property,因此,大多數(shù)的UIElement屬性我們都可以利用其Dependency Property作為目標(biāo)對(duì)象屬性從而與數(shù)據(jù)源建立Binding。
?
l?再有一點(diǎn),建立Binding的數(shù)據(jù)源不一定要是一個(gè)CLR對(duì)象,也可以是XML數(shù)據(jù)、ADO.NET對(duì)象及DependencyObject。
?
關(guān)于為什么binding的對(duì)象一定要是DependencyObject,為什么binding對(duì)象的屬性一定要是dependency property,這個(gè)我就不知道了。
在我第一次看到在XAML中設(shè)置Binding的語法時(shí),簡直是滿頭霧水。這東西到底怎么回事,簡直就沒有章法可循,一會(huì)兒ElementName,一會(huì)兒Source,還有時(shí)什么都沒有,就一個(gè){Binding },再有就是Mode,UpdateSourceTrigger等,簡直沒有頭緒。
?
不過只要打開MSDN,看一下System.Windows.Data.Binding對(duì)象,似乎開始有點(diǎn)感覺了,查看Binding對(duì)象的屬性欄(Properties),你會(huì)發(fā)現(xiàn),原來我們在XAML中設(shè)置Binding時(shí)使用的東西和Binding對(duì)象的屬性好像都是一一對(duì)應(yīng)的。
?
確實(shí)如此,在XAML中設(shè)置Binding就是在這只System.Windows.Data.Binding對(duì)象,這里先提醒一下大家。
?
WPF可不是就這么一個(gè)Binding噢,實(shí)時(shí)上,從BindingBase繼承過來的有三個(gè)兄弟,Binding只是最常用而已。
找到了binding的老家,相信大家對(duì){Binding ElementName=ElemName, Path=PropertyName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, …}這樣的語法應(yīng)該清楚了吧。
那么{Binding }?及{Binding XXXX}這樣的語法呢?其實(shí)可以就是等于new Binding()及new Binding(XXXX),其實(shí)可以考慮成是分別使用了Binding的兩種構(gòu)造方法,而XXXX的作用自然也就清晰了。
其實(shí)和{Binding Path=XXXX}是等價(jià)的,都是設(shè)置Path屬性的。至于這里的Path屬性在我們平常使用時(shí)其實(shí)是用來設(shè)置屬性名的地方,為什么不直接叫做是PropertyName之類的名字呢?這個(gè)又要留著以后思考了。
當(dāng)一個(gè)數(shù)據(jù)源與一個(gè)UIElement形成Binding后,數(shù)據(jù)源的改變,如果傳遞給UIElement的指定屬性?
同樣,當(dāng)UIElement中指定屬性值改變了,如何才能夠通知到數(shù)據(jù)源?要討論這個(gè)問題,需要按數(shù)據(jù)源來分類進(jìn)行討論。這個(gè)分類并不是互斥的之前存在一些交集。
因此,同一種Binding場景可能適用于多種情況。
下面的內(nèi)容是來自MSDN中《Binding Sources Overview》中的內(nèi)容,由于怕翻譯的不好而誤導(dǎo)大家,所以分類的名稱還是使用英文吧。
Using a CLR Class as the Binding Source Object
在典型的Binding情景中,一個(gè)CLR?對(duì)象作為數(shù)據(jù)源,將其中一個(gè)屬性值Binding到某個(gè)UIElement的屬性上(以上面顯示員工姓名的情景為例。
?
用XAML實(shí)現(xiàn)<TextBox Text=”{Binding Source=Employee, Path=EmpName}” />)。當(dāng)數(shù)據(jù)源屬性值變化了,相應(yīng)讓UIElement中對(duì)應(yīng)屬性變化。
?
需要實(shí)現(xiàn)一個(gè)中通知機(jī)制,最簡單的方法是通過實(shí)現(xiàn)INotifyPropertyChanged接口完成此操作。具體實(shí)現(xiàn),可以參考MSDN上的文章《How to: Implement Property Change Notification》。
?
其實(shí)就是實(shí)現(xiàn)了”public?event?PropertyChangedEventHandler PropertyChanged;”事件,通常的做法是在上面加封裝一個(gè)”protected void OnPropertyChanged(string name)”函數(shù)。在屬性的set方法結(jié)尾處,調(diào)用此函數(shù)實(shí)現(xiàn)通知的作用。
?
如果不實(shí)行此接口,則必須自己實(shí)現(xiàn)一套通知系統(tǒng)。為你的類中的每一個(gè)想要實(shí)現(xiàn)通知機(jī)制的屬性創(chuàng)建一個(gè)PropertyChanged模板。
?
即為你的每一個(gè)屬性創(chuàng)建一個(gè)名為”PropertyNameChanged”事件,其中PropertyName是與這個(gè)事件對(duì)應(yīng)的屬性名稱。然后在屬性發(fā)生變化是觸發(fā)這個(gè)事件。(聽起來就麻煩,我也懶得去實(shí)踐驗(yàn)證了)
?
如果以上兩種方法都無法實(shí)現(xiàn)的話,那么就只好在你認(rèn)為需要的時(shí)候顯示的調(diào)用UpdateTarget方法來手動(dòng)更新了。
?
(這種方法沒用過,感覺已經(jīng)失去了Binding的意義了)
Entire Objects Used as a Binding Source
可以理解為將整個(gè)對(duì)象作為數(shù)據(jù)源,與上一個(gè)題目的區(qū)別很小。
?
基本上可以認(rèn)為是原來Binding實(shí)現(xiàn)的是數(shù)據(jù)源屬性與UIElement屬性之間的Binding,而這次是直接將一個(gè)Object對(duì)象與一個(gè)UIElement的屬性進(jìn)行Binding了。
?
這種情況可以使用Binding的Source屬性指明數(shù)據(jù)源(假設(shè)Employee對(duì)象與一個(gè)ListBox實(shí)現(xiàn)banding,用XAML實(shí)現(xiàn)<ListBox ItemsSource=”{Binding Employee}” />),或者還可以將DataContext屬性設(shè)置為Employee(DataContext屬性只有UIElement的一個(gè)子類System.Windows.FrameworkElement及其子類才會(huì)有)。
?
這樣,在設(shè)置ItemsSource時(shí)就可以直接使用”{Binding }”這樣的語法了。當(dāng)然,DataContext屬性設(shè)置成Employee還是需要使用DataContext=”{Binding Employee}”語句的。
?
有人在這里會(huì)嘲笑這一舉動(dòng)實(shí)在是啰嗦,事實(shí)上,DataContext屬性是非常有用的。之所以Binding對(duì)象失敗而最終不得不使用C#語句進(jìn)行Binding就是因?yàn)闆]有設(shè)置DataContext。
?
因?yàn)?#xff0c;當(dāng)我們使用{Binding Source= Employee, Path=”EmpName”}設(shè)置屬性后,WPF查找Source對(duì)象是根據(jù)Element Tree逐級(jí)向上自己的Parent Element查找的,查找每一Element上的DataContext所指定的內(nèi)容是否包含這一Source內(nèi)容,并以第一個(gè)匹配到的結(jié)果作為最終對(duì)象。
?
也就是說,DataContext是按照Element Tree向下繼承的,并且決定這WPF在運(yùn)行時(shí)能否找到我們所制定的Source對(duì)象。即使我們使用{Binding Path=”EmpName”}的語句也是如此。
?
比較常見的做法是,當(dāng)我們有大量的Element需要與一個(gè)數(shù)據(jù)源中的眾多屬性實(shí)現(xiàn)Binding時(shí),我們可以直接在一個(gè)公共Parent Element的DataContext上設(shè)置這一對(duì)象(甚至可以是整個(gè)window或page上),這將會(huì)極大的加少我們重復(fù)的代碼量,同時(shí)也會(huì)是程序更加可讀。
當(dāng)我們需要使用的數(shù)據(jù)源是一個(gè)集合時(shí),如果想要實(shí)現(xiàn)改變通知的機(jī)制。
?
同樣需要實(shí)現(xiàn)一個(gè)接口INotifyCollectionChanged用來在集合發(fā)生改變時(shí)發(fā)起,用法單個(gè)對(duì)象是實(shí)現(xiàn)INotifyPropertyChanged接口類似。
?
首先是將上以前做的不是很好的那一段代碼改成XAML語言實(shí)現(xiàn)。
?
將TextBox標(biāo)簽中的Text屬性與上面listView1中被選定的記錄(listView1.SelectedItem)中對(duì)應(yīng)屬性(例如:ContactID)做Binding。
?
實(shí)現(xiàn)后如圖所示:
<TextBox?Text="{Binding?ElementName=listView1,?Path=SelectedItem.ContactID}"?MinWidth="100" />
?
看以來代碼有點(diǎn)長,而且,下面的幾個(gè)TextBox也都存在大量的重復(fù)內(nèi)容,這里就可以考慮使用上面所說的DataContext了。
將listView1中被選定的記錄(listView1.SelectedItem)作為DataContext放在公共Parent Element上,做法如下:
?
<WrapPanel?Grid.Row="1"?Orientation="Horizontal"?DataContext="{Binding?ElementName=listView1,?Path=SelectedItem}">
然后剩下的代碼就可以簡化很多了:
<StackPanel?Orientation="Horizontal"?Margin="5,2,5,2">
<TextBlock?Text="ContactID:"?TextAlignment="Center" />
<TextBox?Text="{Binding?ContactID}"?MinWidth="100" />
</StackPanel>
<StackPanel?Orientation="Horizontal"?Margin="5,2,5,2">
<TextBlock?Text="FirstName:"?TextAlignment="Center" />
<TextBox?Text="{Binding?FirstName}"?MinWidth="100" />
</StackPanel>
<StackPanel?Orientation="Horizontal"?Margin="5,2,5,2">
<TextBlock?Text="LastName:"?TextAlignment="Center" />
<TextBox?Text="{Binding?EmailAddress}"?MinWidth="100" />
</StackPanel>
<StackPanel?Orientation="Horizontal"?Margin="5,2,5,2">
<TextBlock?Text="EmailAddress:"?TextAlignment="Center" />
<TextBox?Text="{Binding?LastName}"?MinWidth="100" />
</StackPanel>
?
原來的SelectionChanged事件處理方法現(xiàn)在已經(jīng)沒有用了,將多余的代碼去掉:
?
<ListView?Name="listView1"?SelectionChanged="listView1_SelectionChanged"?MinWidth="280"?>
?
后臺(tái)代碼中的對(duì)應(yīng)方法也可以刪掉了private?void?listView1_SelectionChanged(object?sender,?SelectionChangedEventArgs?e)。
?
F5 Debug運(yùn)行一下,結(jié)果和原來是完全一樣的。
在上一文中無得以選擇使用C#實(shí)現(xiàn)Binding的部分代碼,現(xiàn)在使用XAML語言實(shí)現(xiàn),有幾種方案可以選擇,通過如下幾步實(shí)現(xiàn):
1)?將原先建立給listView1建立Binding那一大串代碼刪掉,替換成如下代碼:
listView1.DataContext = dt.DefaultView;
執(zhí)行結(jié)果如下圖所示:
?
?
2)?將其與listView1的ItemsSource屬性建立Binding,設(shè)置每一列的header及DisplayMemberBinding值。
這里由于DataContext的原因,ItemsSource可以寫成"{Binding?}"的形式而其Children Element也都可以簡寫成"{Binding?ContactID}"這樣的形式。
<ListView?Name="listView1"?MinWidth="280"?ItemsSource="{Binding?}">
<ListView.View>
<GridView?x:Name="gridView1">
<GridView.Columns>
<GridViewColumn?DisplayMemberBinding="{Binding?ContactID}"?Header="ContactID"></GridViewColumn>
<GridViewColumn?DisplayMemberBinding="{Binding?FirstName}"?Header="FirstName"></GridViewColumn>
<GridViewColumn?DisplayMemberBinding="{Binding?LastName}"?Header="LastName"></GridViewColumn>
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
改造完后,運(yùn)行結(jié)果會(huì)發(fā)現(xiàn),效果和原來是一樣。效率提高了,代碼更加簡化。
UpdateSourceTrigger??綁定的UpdateSourceTrigger屬性用來控制改變的值何時(shí)傳遞給源。
PropertyChanged??一旦綁定的屬性值改變,源會(huì)立即更新
LostFocus?一旦目標(biāo)控件失去焦點(diǎn),源就會(huì)被更新
Explicit?源不會(huì)更新除非你手動(dòng)來操作
要使用事件綁定需要借助System.Windows. interactivity,如果安裝了Blend,里面就包含了這個(gè)dll。需要在Interaction.Triggers里面添加一個(gè)或多個(gè)EventTrigger并指定關(guān)注的的事件名稱,在EventTrigger中通過InvokeCommandAction來綁定事件對(duì)應(yīng)的命令。圖中所示綁定了主窗口的Loaded事件,在事件觸發(fā)后會(huì)調(diào)用綁定的命令對(duì)象LoadedCommand的Execute方法執(zhí)行命令,當(dāng)命令綁定需要參數(shù)時(shí)可以通過綁定CommandParameter實(shí)現(xiàn)。需要指出的是之前在實(shí)現(xiàn)MyCommand的Execute方法時(shí)我們加入了CanExecute的判斷,因此事件觸發(fā)后是否能夠真正執(zhí)行綁定的命令也受到綁定的LoadedCommand的CanExecute方法的影響。
?
https://www.cnblogs.com/durow/p/4860836.html
注意;
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"就是導(dǎo)入Blend的dll,然后在控件內(nèi)部用<i:Interaction.Triggers/>即可,其它應(yīng)該一看就知道,我通過事件觸發(fā)器,來引發(fā)ViewModel中兩個(gè)Command,第二個(gè)Command的參數(shù)是Button對(duì)象,通過ElementName=btn來指定。
<Button Name="btn" Content="Button" Height="33"? VerticalAlignment="Top" Width="109">
?? ??? ?<i:Interaction.Triggers>
?? ??? ??? ??<i:EventTrigger EventName="Click">
?? ??? ??? ??? ? ?<i:InvokeCommandAction Command="{Binding Command1}" CommandParameter="10" />
? ? ? ? ? ? ?</i:EventTrigger>
? ? ? ? ? ? <i:EventTrigger EventName="MouseMove">
? ? ? ? ? ? ? <i:InvokeCommandAction Command="{Binding Command2}" CommandParameter="{Binding ElementName=btn}" />
? ? ? ? ? ? </i:EventTrigger>
? ? ? ?</i:Interaction.Triggers>
?</Button>
---------------------?
進(jìn)行Bingding時(shí),如果明確知道數(shù)據(jù)源的Name,就能用Source或者ElementName進(jìn)行綁定,但是有時(shí)候我們需要綁定的數(shù)據(jù)源可能沒有明確的Name,此時(shí)我們就需要利用Bingding的RelativeSource進(jìn)行綁定。
一、控件關(guān)聯(lián)自身的屬性
?<TextBox Name="textbox" FontSize="24" Margin="10"
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Text="{Binding RelativeSource={RelativeSource Mode=Self},Path=Name}"/>
二、控件關(guān)聯(lián)其父級(jí)容器的屬性
<TextBox Name="textbox" Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Grid},AncestorLevel=1},Path=Name}"/>
RelativeSource屬性的數(shù)據(jù)類型為RelativeSource類,AncestorLevel指的是以Bingding目標(biāo)控件為起點(diǎn)的層級(jí)偏移量,d2的偏移量是1,g2的偏移量是2,AncestorType指的是要找的目標(biāo)對(duì)象的類型。值得注意的是AncestorLevel需要參考AncestorType使用,如上面設(shè)置了AncestorType={x:Type Grid},則Bingding在尋找時(shí)會(huì)忽略非Grid的控件,此時(shí)g2的偏移量是1,g1的偏移量是2,DockPanel被忽略。
將一個(gè)Behavior拖到一個(gè)元素上,就能使這個(gè)元素具有某種行為,而實(shí)現(xiàn)這種行為的程序集和你的項(xiàng)目是獨(dú)立的,你創(chuàng)建的Behavior也可以被其他人使用。
public class MouseDoubleClickCopyTextBehavior : Behavior<FrameworkElement>
? ? {
? ? ? ? /// <summary>
? ? ? ? /// 需要復(fù)制的內(nèi)容
? ? ? ? /// </summary>
? ? ? ? public string CopyText
? ? ? ? {
? ? ? ? ? ? get { return (string)GetValue(CopyTextProperty); }
? ? ? ? ? ? set { SetValue(CopyTextProperty, value); }
? ? ? ? }
? ? ? ? public static readonly DependencyProperty CopyTextProperty = DependencyProperty.Register("CopyText", typeof(string), typeof(MouseDoubleClickCopyTextBehavior), new PropertyMetadata(null));
? ? ? ? protected override void OnAttached()
? ? ? ? {
? ? ? ? ? ? base.OnAttached();
? ? ? ? ? ? AssociatedObject.PreviewMouseLeftButtonDown += AssociatedObject_PreviewMouseLeftButtonDown;
? ? ? ? }
? ? ? ? protected override void OnDetaching()
? ? ? ? {
? ? ? ? ? ? base.OnDetaching();
? ? ? ? ? ? AssociatedObject.PreviewMouseLeftButtonDown -= AssociatedObject_PreviewMouseLeftButtonDown;
? ? ? ? }
? ? ? ? void AssociatedObject_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
? ? ? ? {
? ? ? ? ? ? if (e.ClickCount >= 2)
? ? ? ? ? ? ? ? Clipboard.SetDataObject(CopyText);
? ? ? ? }
獲取構(gòu)成在合并字典的各種資源字典 ResourceDictionary 字典的集合??合并多個(gè)外部資源字典成為本地字典
合并多個(gè)外部資源字典成為本地字典。當(dāng)需要合并更多字典的時(shí)候只要在ResourceDictionary.MergedDictionaries節(jié)中順序增加引用。
合并字典(MergedDictionaries 集合中的字典)中對(duì)同一對(duì)象的同一子元素進(jìn)行定義的時(shí)候,會(huì)產(chǎn)生覆蓋效果:在這種情況下,所返回的資源將來自在 MergedDictionaries 集合中最后一個(gè)找到的字典。(在這里會(huì)顯示myresourcedictionary2.xaml中的定義)。
合并字典(MergedDictionaries 集合中的字典)中對(duì)同一對(duì)象的不同子元素定義的時(shí)候會(huì)產(chǎn)生疊加效果。
?<UserControl.Resources>
? ? ? ? <ResourceDictionary>
? ? ? ? ? ? <ResourceDictionary.MergedDictionaries>
? ? ? ? ? ? ? ? <ResourceDictionary Source="xxx.xaml"></ResourceDictionary>
? ? ? ? ? ? </ResourceDictionary.MergedDictionaries>
? ? ? ? </ResourceDictionary>
? ? </UserControl.Resources>
總結(jié)
- 上一篇: 亿阳信通笔试题
- 下一篇: 双硬盘安装Windows+Ubuntu