問題一:在某一些情況下,我們使用MVVM模式的時候,對于某一個字段(AgeField)需要在前台的很多個控件(A、B、C、D、E)進行綁定,但是如何能夠讓我們背景字段名改變的時候能夠非常友善的改變所有使用了這個字段的控件呢?
回答:使用Element to Element Binding,将AgeFiled綁定到A控件,然後再讓B、C、D、E控件綁定A控件的使用AgeField字段的屬性。
例如:字段(AgeField)的資料是年齡大小,A、B、C、D、E控件分别是 Ellipse、Label、Slider、TextBox、ProgressBar,這些字段的Width、Value或者Text值按照正常的做法, 這幾個控件都是在MVVM模式下都是綁定的AgeField。但是這個字段名在後期代碼維護的時候修改為Age了,我們就不得不需要一一修改五個控件的綁 定值。如果這幾個控件還分布在不同位置,那麼尋找起來就将更加麻煩。那麼這裡我們就将使用到Silverlight 3的一個新特性Element to Element Binding。
執行個體一:我們在這裡有一個TextBox控件tbAge,其Value值假定綁定到某一個字 段,然後我們再添加Slider、ProgressBar、Ellipse控件,使用Value="{Binding Text,ElementName=tbAge,Mode=TwoWay}"這樣的方式将tbAge的Text值綁定到這幾個控件上。下面我們看源碼如 下:
<!--這裡是資料源-->
<TextBox x:Name="tbAge" Text="30" Width="80" Margin="0,87,0,183" Height="30"
HorizontalAlignment="Left" VerticalAlignment="Top"/>
<!--Silder控件綁定上面的tbAge控件的值-->
<Slider Name="sdAge" Value="{Binding ElementName=tbAge, Path=Text, Mode=TwoWay }"
Minimum="1" Maximum="100" Height="40" Width="210" HorizontalAlignment="Left"
VerticalAlignment="Top" Margin="0,145,0,115"></Slider>
<!--ProgressBar控件綁定上面的tbAge控件的值-->
<ProgressBar Value="{Binding Text,ElementName=tbAge,Mode=TwoWay}" Margin="0,27,0,0"
Name="progressBar1" Height="24" HorizontalAlignment="Left"
VerticalAlignment="Top" Width="210" />
<!--Ellipse的Width屬性綁定sdAge控件的值-->
<Ellipse Width="{Binding Value,ElementName=sdAge,Mode=TwoWay}"
Height="100" HorizontalAlignment="Left" Margin="0,200,0,0"
Name="ellipse1" Stroke="Black" StrokeThickness="1" VerticalAlignment="Top" />
問題二:為什麼在Silverlight中我們更常用ObservableCollection<T>來作為資料集合綁定到控件中,而不是使用List<T>呢?
回答:當T繼承于INotifyPropertyChanged接口的時候,如果T的屬性值發 生變化時,ObservableCollection和List都能夠讓前台UI發生相應的改變。但是當增加一個T的資料行時,List不能及時更新前台 UI,而ObservableCollection能夠将新增的T資料行馬上更新到UI上去。
執行個體二:我們拖出兩個DataGrid控件分别是ShowListCity和ShowObservableCity,然後分别綁定資料List和Observable資料,再添加一個按鈕為這兩個資料集合添加集合值。看UI是否變化。下面我們看源碼如下:
<sdk:DataGrid HorizontalAlignment="Left" AutoGenerateColumns="False" Margin="476,12,0,0"
Name="ShowListCity" VerticalAlignment="Top" Height="169" Width="324" >
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn Header="省會" Binding="{Binding AddrName}" IsReadOnly="True" Width="108"/>
<sdk:DataGridTextColumn Header="城市" Binding="{Binding CityName}" IsReadOnly="True" Width="108"/>
<sdk:DataGridTextColumn Header="電話區号" Binding="{Binding TelNum}" IsReadOnly="True" Width="108"/>
</sdk:DataGrid.Columns>
</sdk:DataGrid>
<sdk:DataGrid HorizontalAlignment="Left" AutoGenerateColumns="False" Margin="476,187,0,0"
Name="ShowObservableCity" VerticalAlignment="Top" Height="180" Width="324" >
<Button Content="添加條目" Height="23" HorizontalAlignment="Left" Margin="364,13,0,0" Name="button1"
VerticalAlignment="Top" Width="75" Click="button1_Click" />
下面是MainPage.xaml.cs代碼
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
ListCity = new List<CityInformation>()
{
new CityInformation(){ AddrName="四川", CityName="成都", TelNum="028"},
new CityInformation(){ AddrName="北京", CityName="北京", TelNum="010"},
new CityInformation(){ AddrName="廣東", CityName="廣州", TelNum="021"}
};
ObservableCity = new ObservableCollection<CityInformation>()
this.ShowListCity.ItemsSource = ListCity;
this.ShowObservableCity.ItemsSource = ObservableCity;
}
private List<CityInformation> _ListCity;
/// <summary>
/// 城市集合
/// </summary>
public List<CityInformation> ListCity
get { return _ListCity; }
set { _ListCity = value; }
private ObservableCollection<CityInformation> _ObservableCity;
public ObservableCollection<CityInformation> ObservableCity
get { return _ObservableCity; }
set { _ObservableCity = value; }
private void button1_Click(object sender, RoutedEventArgs e)
ListCity.Add(new CityInformation() { AddrName = "重慶", CityName = "重慶", TelNum = "022" });
ObservableCity.Add(new CityInformation() { AddrName = "重慶", CityName = "重慶", TelNum = "022" });
}
下面我們來看CityInformation執行個體類代碼如下:
/// <summary>
/// 城市資訊的實體類
/// </summary>
public class CityInformation
private string _AddrName;
private string _CityName;
private string _TelNum;
/// 位址名
public string AddrName
get { return _AddrName; }
set { _AddrName = value; }
/// 城市名
public string CityName
get { return _CityName; }
set { _CityName = value; }
/// 區号
public string TelNum
get { return _TelNum; }
set { _TelNum = value; }
}
本文轉自程興亮 51CTO部落格,原文連結:http://blog.51cto.com/chengxingliang/826745