MVVMLight項目的綁定及各種使用場景示例分析
一、綁定:
主要包含元素綁定和非元素綁定兩種。
1、元素綁定:
是綁定的最簡單形式,源對象是WPF的元素,并且源對象的屬性是依賴項屬性。
根據(jù)我們之前的知識 ,依賴項屬性具有內(nèi)置的更改通知支持。所以當(dāng)我們的源對象中改變依賴項屬性的值時,會立即更新目標對象中的綁定屬性。
以上篇的例子來重寫,我們不用額外定義全局公開的屬性來支持數(shù)據(jù)的顯示。
如下:
<StackPanel Orientation="Vertical" HorizontalAlignment="Left" > <TextBox x:Name="WelcomeText" Width="200" Margin="10,10,0,0"></TextBox> <TextBlock Text="{Binding ElementName=WelcomeText,Path=Text,StringFormat='Hello \{0\}'}" Margin="10,10,0,0"></TextBlock> </StackPanel>
TextBlock 綁定了名稱為WelcomeText的元素,并且將Path指向Text屬性,所以他的值會跟著 WelcomeText的變化而變化。
2、非元素類型綁定:
2.1 Source屬性:
綁定具體的數(shù)據(jù)對象:如系統(tǒng)信息跟我們定義的資源數(shù)據(jù)。
定義Window下的全局資源
<Window.Resources> <SolidColorBrush x:Key="BorderBrush">Red</SolidColorBrush> </Window.Resources>
應(yīng)用到視圖中
<StackPanel Margin="10,50,0,0" Orientation="Vertical" > <TextBlock Text="{Binding Source={x:Static SystemFonts.IconFontFamily},Path=Source}" ></TextBlock> <TextBlock Text="{Binding Source={StaticResource BorderBrush}}" Foreground="{Binding Source={StaticResource BorderBrush}}" ></TextBlock> </StackPanel>
結(jié)果:
2.2 RelativeSource 屬性:
設(shè)置該屬性 可以根據(jù)當(dāng)前目標對象的相對關(guān)系指向源目標。比如獲取當(dāng)前對象的父親對象、兄弟對象或者自身的其他屬性等一些數(shù)據(jù)。
<StackPanel Margin="10,50,0,0" Orientation="Vertical" ToolTip="top" > <StackPanel Orientation="Horizontal" > <TextBlock Width="150" Text="獲取自身寬度:" ></TextBlock> <TextBlock Width="200" Text="{Binding Path=Width,RelativeSource={RelativeSource Mode=Self}}" ></TextBlock> </StackPanel> <StackPanel Orientation="Horizontal" ToolTip="parent" > <TextBlock Width="150" Text="查找上一層ToolTip:" ></TextBlock> <TextBlock Text="{Binding Path=ToolTip,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type StackPanel}}}"></TextBlock> </StackPanel> <StackPanel Orientation="Horizontal"> <TextBlock Width="150" Text="查找上二層ToolTip:" ></TextBlock> <TextBlock Text="{Binding Path=ToolTip,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type StackPanel},AncestorLevel=2}}"></TextBlock> </StackPanel> </StackPan>
代碼很容易理解,這邊在創(chuàng)建RelativeSource的時候,mode模式有四種類型:
Mode成員名稱 | 說明 | |
---|---|---|
FindAncestor | 引用數(shù)據(jù)綁定元素的父鏈中的上級。 這可用于綁定到特定類型的上級或其子類。 若要指定 AncestorType 和/或 AncestorLevel,這就是應(yīng)使用的模式。 | |
PreviousData | 允許在當(dāng)前顯示的數(shù)據(jù)項列表中綁定上一個數(shù)據(jù)項(不是包含數(shù)據(jù)項的控件)。 | |
Self | 引用正在其上設(shè)置綁定的元素,并允許你將該元素的一個屬性綁定到同一元素的其他屬性上。 | |
TemplatedParent | 引用應(yīng)用了模板的元素,其中此模板中存在數(shù)據(jù)綁定元素。 這類似于設(shè)置 TemplateBindingExtension,且僅在 Binding 位于模板內(nèi)部時適用。 |
注意:AncestorType 指得是查找的對象類型,AncestorLevel 代表搜索的層級的位置,如果是3,則忽略前兩個發(fā)現(xiàn)的元素。
結(jié)果:
2.3 DataContext 屬性:
如果想將一個對象綁定到一個由多個元素組成的視圖塊或者復(fù)合元素中,用DataContext 會更好開發(fā)和維護。如下
<StackPanel Orientation="Vertical" DataContext="UInfo" > <StackPanel Orientation="Horizontal" > <TextBlock Text="名稱:" Width="100" ></TextBlock> <TextBox Text="{Binding Name}" Width="100" ></TextBox> </StackPanel> <StackPanel Orientation="Horizontal"> <TextBlock Text="性別:" Width="100" ></TextBlock> <TextBox Text="{Binding Sex}" Width="100" ></TextBox> </StackPanel> </StackPanel>
二、綁定的各種使用場景:
數(shù)據(jù)綁定有普通的控件綁定應(yīng)用:比如 下拉框、單選框、復(fù)選框、普通文本框 、日期框等;
復(fù)雜的綁定有數(shù)據(jù)列表綁定,用戶控件信息綁定等,比如 ListBox,DataGrid,UserControl綁定等。
1、下拉框:
View代碼:
<StackPanel Margin="10,20,0,50"> <TextBlock Text="下拉框" FontWeight="Bold" FontSize="12" Margin="0,5,0,5" ></TextBlock> <DockPanel x:Name="Combbox" > <StackPanel DockPanel.Dock="Left" Width="240"> <ComboBox Width="200" HorizontalAlignment="Left" ItemsSource="{Binding CombboxList}" SelectedItem="{Binding CombboxItem}" DisplayMemberPath="Text" SelectedValuePath="Key" ></ComboBox> </StackPanel> <StackPanel DockPanel.Dock="Right" Width="240" Orientation="Horizontal" DataContext="{Binding CombboxItem}" > <TextBlock Text="{Binding Key,StringFormat='結(jié)果:\{0\}'}" Margin="0,0,15,0" ></TextBlock> <TextBlock Text="{Binding Text}"></TextBlock> </StackPanel> </DockPanel> </StackPanel>
Model代碼:
public class ComplexInfoModel:ObservableObject { private String key; /// <summary> /// Key值 /// </summary> public String Key { get { return key; } set { key = value; RaisePropertyChanged(()=>Key); } } private String text; /// <summary> /// Text值 /// </summary> public String Text { get { return text; } set { text = value; RaisePropertyChanged(()=>Text); } } }
ViewModel代碼:
#region 下拉框相關(guān) private ComplexInfoModel combboxItem; /// <summary> /// 下拉框選中信息 /// </summary> public ComplexInfoModel CombboxItem { get { return combboxItem; } set { combboxItem = value; RaisePropertyChanged(() => CombboxItem); } } private List<ComplexInfoModel> combboxList; /// <summary> /// 下拉框列表 /// </summary> public List<ComplexInfoModel> CombboxList { get { return combboxList; } set { combboxList = value; RaisePropertyChanged(()=>CombboxList); } } #endregio
說明:CombboxItem是一個全局的屬性,作用在當(dāng)前頁面的數(shù)據(jù)上下文中,結(jié)果顯示的內(nèi)容指向下拉框中的選中值,達到共用一個數(shù)據(jù)的目的。
這邊有四個地方需要注意的:ItemsSource:數(shù)據(jù)源;SelectedItem:選中的項;DisplayMemberPath:綁定時顯示的所屬值;SelectedValuePath :綁定時候key的所屬值。
結(jié)果:
2、單選框
<StackPanel Margin="10,0,0,50"> <TextBlock Text="單選框" FontWeight="Bold" FontSize="12" Margin="0,5,0,5" ></TextBlock> <DockPanel x:Name="RadioButton" > <StackPanel DockPanel.Dock="Left" Width="240"> <RadioButton Content="{Binding SingleRadio}" IsChecked="{Binding IsSingleRadioCheck}" HorizontalAlignment="Right" Width="240" > </RadioButton> </StackPanel> <StackPanel DockPanel.Dock="Right" Width="240" Orientation="Horizontal"> <TextBlock Text="{Binding IsSingleRadioCheck,StringFormat='結(jié)果:\{0\}'}" ></TextBlock> </StackPanel> </DockPanel> </StackPanel>
說明:注意這邊使用到了兩個屬性: SingleRadio,IsSingleRadioCheck,一個用于顯示單選框內(nèi)容,一個用于表示是否選中
結(jié)果:
3、組合單選框
我們一般會用單選框做組合表示唯一選項,比如性別包含男女,但是只能選擇一個。而更多的場景是包含多個選項,但是只能單選的,這時候就需要做單選框組。
<StackPanel Margin="10,0,0,50"> <TextBlock Text="組合單選框" FontWeight="Bold" FontSize="12" Margin="0,5,0,5"></TextBlock> <DockPanel x:Name="GroupRadioButton" > <StackPanel DockPanel.Dock="Left" Width="240"> <ItemsControl ItemsSource="{Binding RadioButtons}"> <ItemsControl.ItemTemplate> <DataTemplate> <RadioButton Content="{Binding Content}" IsChecked="{Binding IsCheck}" GroupName="RadioButtons" Command="{Binding DataContext.RadioCheckCommand,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ItemsControl}}"> </RadioButton> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> </StackPanel> <StackPanel DockPanel.Dock="Right" Width="240" Orientation="Horizontal"> <TextBlock Text="{Binding RadioButton.Content,StringFormat='結(jié)果:\{0\}'}" ></TextBlock> </StackPanel> </DockPanel> </StackPanel
這邊使用了ItemsControl,可以根據(jù)模板來定義內(nèi)容,我們在模板中放置我們需要用到的內(nèi)容。這邊需要注意的是:GroupName用一樣的,來代表這是一個單選控件組合。
這邊有是三個屬性進行綁定相關(guān):
RadioButtons:單選框列表數(shù)據(jù)(循環(huán)綁定);Content:單選框顯示的內(nèi)容;IsCheck:單選框的是否選中。
結(jié)果:
4、復(fù)選框,復(fù)選框與單選框的使用情況類似:
<StackPanel Margin="10,0,0,50"> <TextBlock Text="復(fù)合框" FontWeight="Bold" FontSize="12" Margin="0,5,0,5" ></TextBlock> <DockPanel x:Name="GroupCheckButton" > <StackPanel DockPanel.Dock="Left" Width="240"> <ItemsControl ItemsSource="{Binding CheckButtons}" x:Name="cbt" > <ItemsControl.ItemTemplate> <DataTemplate> <CheckBox Content="{Binding Content}" IsChecked="{Binding IsCheck}" Command="{Binding DataContext.CheckCommand,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ItemsControl}}"/> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> </StackPanel> <StackPanel DockPanel.Dock="Right" Width="240" Orientation="Horizontal"> <TextBlock Text="{Binding CheckInfo,StringFormat='結(jié)果:\{0\}'}" ></TextBlock> </StackPanel> </DockPanel> </StackPanel>
結(jié)果:
5、樹形控件
View代碼:
<StackPanel Margin="10,0,0,50"> <TextBlock Text="樹" FontWeight="Bold" FontSize="12" Margin="0,5,0,5" ></TextBlock> <DockPanel x:Name="TreeButton" > <StackPanel DockPanel.Dock="Left" Width="240"> <TreeView ItemsSource="{Binding TreeInfo}" x:Name="tree" BorderThickness="0"> <TreeView.ItemTemplate> <HierarchicalDataTemplate ItemsSource="{Binding Children}"> <TextBlock Text="{Binding NodeName}"/> </HierarchicalDataTemplate> </TreeView.ItemTemplate> </TreeView> </StackPanel> <StackPanel DockPanel.Dock="Right" Width="240" Orientation="Horizontal" DataContext="{Binding SelectedItem,ElementName=tree}"> <TextBlock Text="結(jié)果:"/> <TextBlock Text="{Binding NodeID,StringFormat='NodeID:\{0\}'}" Margin="0,0,20,0" /> <TextBlock Text="{Binding NodeName,StringFormat='NodeName:\{0\}'}"/> </StackPanel> </DockPanel> </StackPanel>
Model代碼
public class TreeNodeModel : ObservableObject { public string NodeID { get; set; } public string NodeName { get; set; } public List<TreeNodeModel> Children { get; set; } }
ViewModel代碼
#region 樹控件 private List<TreeNodeModel> treeInfo; /// <summary> /// 樹控件數(shù)據(jù)信息 /// </summary> public List<TreeNodeModel> TreeInfo { get { return treeInfo; } set { treeInfo = value; RaisePropertyChanged(()=>TreeInfo); } } #endregion
結(jié)果:
6、ListBox
當(dāng)我們需要用到循環(huán)的列表內(nèi)容,并且模板化程度高的時候,建議使用ListBox來做綁定。
View代碼:
<StackPanel Margin="10,0,0,50" Orientation="Vertical" > <TextBlock Text="ListBox模板" FontWeight="Bold" FontSize="12" Margin="0,5,0,5" ></TextBlock> <DockPanel > <StackPanel HorizontalAlignment="Left" DockPanel.Dock="Left" > <ListBox x:Name="lb" ItemsSource="{Binding ListBoxData}" Width="500" BorderThickness="0" > <ListBox.ItemsPanel> <ItemsPanelTemplate> <WrapPanel Width="{Binding ActualWidth,RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}"/> </ItemsPanelTemplate> </ListBox.ItemsPanel> <ListBox.ItemTemplate> <DataTemplate> <StackPanel> <Image Source="{Binding Img}" Width="96" Height="96"/> <TextBlock HorizontalAlignment="Center" Text="{Binding Info}"/> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </StackPanel> <StackPanel DockPanel.Dock="Right" DataContext="{Binding SelectedItem,ElementName=lb}" Margin="15" Orientation="Vertical" > <TextBlock Text="{Binding Info,StringFormat='選中:\{0\}'}" ></TextBlock> </StackPanel> </DockPanel> </StackPanel>
ViewModel代碼:
#region ListBox 模板 private IEnumerable listBoxData; /// <summary> /// LisBox數(shù)據(jù)模板 /// </summary> public IEnumerable ListBoxData { get { return listBoxData; } set { listBoxData = value;RaisePropertyChanged(()=>ListBoxData); } } #endregion
初始數(shù)據(jù):
private void InitListBoxList() { ListBoxData = new ObservableCollection<dynamic>(){ new { Img="/MVVMLightDemo;component/Images/1.jpg",Info="櫻桃" }, new { Img="/MVVMLightDemo;component/Images/2.jpg",Info="葡萄" }, new { Img="/MVVMLightDemo;component/Images/3.jpg",Info="蘋果" }, new { Img="/MVVMLightDemo;component/Images/4.jpg",Info="獼猴桃" }, new { Img="/MVVMLightDemo;component/Images/5.jpg",Info="檸檬" }, };
結(jié)果:
7、用戶控件的集合綁定:
ListBox的列表綁定遠遠不能滿足我們實際工作中的需求,
出于對靈活性、復(fù)用性以及代碼精簡的考慮,需要保證循環(huán)列表中的單個元素是獨立的元素片段,類似Web中的局部視圖。 這時候,使用用戶控件會好很多。
我們先寫一個用戶控件,分別設(shè)置了他的樣式和綁定的屬性值,如下:
<UserControl x:Class="MVVMLightDemo.Content.FruitInfoView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300"> <Grid> <Grid.Resources> <Style TargetType="{x:Type StackPanel}"> <Style.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="RenderTransform"> <Setter.Value> <RotateTransform Angle="10"></RotateTransform> </Setter.Value> </Setter> <Setter Property="Background" Value="#3B9CFB" /> </Trigger> </Style.Triggers> </Style> </Grid.Resources> <StackPanel Orientation="Vertical" Margin="10"> <Image Source="{Binding Img}" Width="96" Height="96" /> <TextBlock HorizontalAlignment="Center" Text="{Binding Info}"/> </StackPanel> </Grid> </UserControl>
在目標視圖頁面注冊并使用:
xmlns:Content="clr-namespace:MVVMLightDemo.Content"
<StackPanel Margin="10,0,0,50" Orientation="Vertical" > <TextBlock Text="用戶控件模板列表" FontWeight="Bold" FontSize="12" Margin="0,5,0,5" ></TextBlock> <StackPanel HorizontalAlignment="Left" Width="500" > <ItemsControl ItemsSource="{Binding FiList}" HorizontalAlignment="Left" > <ItemsControl.ItemTemplate> <DataTemplate> <Content:FruitInfoView /> </DataTemplate> </ItemsControl.ItemTemplate> <!-- 面板顯示模板 --> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <WrapPanel Orientation="Horizontal"> </WrapPanel> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> </ItemsControl> </StackPanel> </StackPanel>
結(jié)果:
后記:這篇更確切的說是綁定的相關(guān)知識,只是應(yīng)用了MVVM模式來實現(xiàn)。
工作太忙了,寫的太慢,其實后面幾篇都已經(jīng)成稿了,一直放在Note里面等待認真檢查,品質(zhì)太差怕誤導(dǎo)其他開發(fā)人員。
以上就是MVVMLight項目的綁定及各種使用場景示例分析的詳細內(nèi)容,更多關(guān)于MVVMLight項目的綁定及各種使用場景的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android開發(fā)之imageView圖片按比例縮放的實現(xiàn)方法
這篇文章主要介紹了Android開發(fā)之imageView圖片按比例縮放的實現(xiàn)方法,較為詳細的分析了Android中ImageView控件的scaleType屬性控制圖片縮放的具體用法,需要的朋友可以參考下2016-01-01Flutter?Widget?之StatefulBuilder構(gòu)建方法詳解
這篇文章主要為大家介紹了Flutter?Widget?之StatefulBuilder構(gòu)建方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-11-11