1. 程式人生 > >WPF中的數據綁定Data Binding使用小結

WPF中的數據綁定Data Binding使用小結

表示 ins preview info formate sso eas key 多個

完整的數據綁定的語法說明可以在這裏查看:

http://www.nbdtech.com/Free/WpfBinding.pdf

MSDN資料:

Data Binding: Part 1 http://msdn.microsoft.com/en-us/library/aa480224.aspx

Data Binding: Part 2 http://msdn.microsoft.com/en-us/library/aa480226.aspx

Data Binding Overview http://msdn.microsoft.com/en-us/library/ms752347.aspx

技術分享

INotifyPropertyChanged接口

綁定的數據源對象一般都要實現INotifyPropertyChanged接口。

{Binding} 說明了被綁定控件的屬性的內容與該控件的DataContext屬性關聯,綁定的是其DataContext代表的整個控件的內容。如下:
<ContentControl Name="LongPreview" Grid.Row="2" Content="{Binding}" HorizontalAlignment="Left"/>
ContentControl 只是一個純粹容納所顯示內容的一個空控件,不負責如何具體顯示各個內容,借助於DataTemplate可以設置內容的顯示細節。

使用參數Path

(使用父元素的DataContext)使用參數綁定,且在數值變化時更新數據源。(兩種寫法)

<TextBox Text="{Binding Path=Name, UpdateSourceTrigger=PropertyChanged}"/>
<TextBox.Text>
<Binding Path="StartPrice" UpdateSourceTrigger="PropertyChanged"/>
</TextBox.Text>

相對資源RelativeSource

RelativeSource={RelativeSource Self}是一個特殊的綁定源,表示指向當前元素自己。自己綁定自己,將ToolTip屬性綁定到Validation.Errors中第一個錯誤項的錯誤信息(Validation.Errors)[0].ErrorContent。

技術分享 技術分享 <Style x:Key="textStyleTextBox" TargetType="{x:Type TextBox}">
<Setter Property="Foreground" Value="#333333" />
<Setter Property="MaxLength" Value="40" />
<Setter Property="Width" Value="392" />
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style> 技術分享

使用轉換器和驗證規則

技術分享 技術分享 <TextBox Name="StartDateEntryForm" Grid.Row="3" Grid.Column="1" Style="{StaticResource textStyleTextBox}" Margin="8,5,0,5" Validation.ErrorTemplate="{StaticResource validationTemplate}">
<TextBox.Text>
<Binding Path="StartDate" UpdateSourceTrigger="PropertyChanged" Converter="{StaticResource dateConverter}">
<Binding.ValidationRules>
<src:FutureDateRule/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>

//自定義的驗證規則須從ValidationRule繼承。
class FutureDateRule : ValidationRule
{
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
DateTime date;
try
{
date = DateTime.Parse(value.ToString());
}
catch (FormatException)
{
return new ValidationResult(false, "Value is not a valid date.");
}
if (DateTime.Now.Date > date)
{
return new ValidationResult(false, "Please enter a date in the future.");
}
else
{
return new ValidationResult(true, null);
}
}
} 技術分享

使用數據觸發器

SpecialFeatures是一個枚舉數據類型。

技術分享 技術分享 <DataTrigger Binding="{Binding Path=SpecialFeatures}">
<DataTrigger.Value>
<src:SpecialFeatures>Color</src:SpecialFeatures>
</DataTrigger.Value>
<Setter Property="BorderBrush" Value="DodgerBlue" TargetName="border" />
<Setter Property="Foreground" Value="Navy" TargetName="descriptionTitle" />
<Setter Property="Foreground" Value="Navy" TargetName="currentPriceTitle" />
<Setter Property="BorderThickness" Value="3" TargetName="border" />
<Setter Property="Padding" Value="5" TargetName="border" />
</DataTrigger> 技術分享

多重綁定

綁定源是多個源,綁定目標與綁定源是一對多的關系。

技術分享 技術分享 <ComboBox.IsEnabled>
<MultiBinding Converter="{StaticResource specialFeaturesConverter}">
<Binding Path="CurrentUser.Rating" Source="{x:Static Application.Current}"/>
<Binding Path="CurrentUser.MemberSince" Source="{x:Static Application.Current}"/>
</MultiBinding>
</ComboBox.IsEnabled>
//自定義的轉換器須實現IMultiValueConverter接口。
class SpecialFeaturesConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
//數組中的對象數值的索引順序與XAML文件的多重綁定定義有關。
int rating = (int)values[0];
DateTime date = (DateTime)values[1];

return ((rating >= 10) && (date.Date < (DateTime.Now.Date - new TimeSpan(365, 0, 0, 0))));
}

public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
return new object[2] { Binding.DoNothing, Binding.DoNothing };
}
} 技術分享

Master-Detail:主-從應用(使用CollectionViewSource)

技術分享主從應用

說明:
AuctionItems的定義為:public ObservableCollection<AuctionItem> AuctionItems 。
在 ListBox 中直接使用 CollectionViewSource 來表示主數據(AuctionItem集合),在 ContentControl 中則同時使用設定 Content 和 ContentControl 兩個屬性, Content 直接指向CollectionViewSource, ContentControl 則使用先前已經定義的數據模板綁定(數據模板中的數據項則是綁定到AuctionItem類的各個屬性)。

數據分組(使用CollectionViewSource)
分組表頭項的數據模板:
<DataTemplate x:Key="groupingHeaderTemplate">
<TextBlock Text="{Binding Path=Name}" Foreground="Navy" FontWeight="Bold" FontSize="12" />
</DataTemplate>
在ListBox中使用分組:
<ListBox Name="Master" Grid.Row="2" Grid.ColumnSpan="3" Margin="8" ItemsSource="{Binding Source={StaticResource listingDataView}}">
<ListBox.GroupStyle>
<GroupStyle HeaderTemplate="{StaticResource groupingHeaderTemplate}"/>
</ListBox.GroupStyle>
</ListBox>
分組開關:
<CheckBox Name="Grouping" Grid.Row="1" Grid.Column="0" Margin="8" Style="{StaticResource checkBoxStyle}" Checked="AddGrouping" Unchecked="RemoveGrouping">Group by category</CheckBox>
CheckBox的事件處理:
private void AddGrouping(object sender, RoutedEventArgs e)
{
PropertyGroupDescription pgd = new PropertyGroupDescription();
pgd.PropertyName = "Category"; //使用屬性Category的數值來分組
listingDataView.GroupDescriptions.Add(pgd);
}
private void RemoveGrouping(object sender, RoutedEventArgs e)
{
listingDataView.GroupDescriptions.Clear();
}

排序數據(使用CollectionViewSource) 比分組簡單
排序開關:
<CheckBox Name="Sorting" Grid.Row="1" Grid.Column="3" Margin="8" Style="{StaticResource checkBoxStyle}" Checked="AddSorting" Unchecked="RemoveSorting">Sort by category and date</CheckBox>
CheckBox的事件處理:
private void AddSorting(object sender, RoutedEventArgs e)
{
listingDataView.SortDescriptions.Add(new SortDescription("Category", ListSortDirection.Ascending));
listingDataView.SortDescriptions.Add(new SortDescription("StartDate", ListSortDirection.Descending));
}
private void RemoveSorting(object sender, RoutedEventArgs e)
{
listingDataView.SortDescriptions.Clear();
}

過濾數據(使用CollectionViewSource) 跟排序類似
過濾開關:
<CheckBox Name="Filtering" Grid.Row="1" Grid.Column="1" Margin="8" Style="{StaticResource checkBoxStyle}" Checked="AddFiltering" Unchecked="RemoveFiltering">Show only bargains</CheckBox>
CheckBox的事件處理:
private void AddFiltering(object sender, RoutedEventArgs e)
{
listingDataView.Filter += new FilterEventHandler(ShowOnlyBargainsFilter);
}
private void RemoveFiltering(object sender, RoutedEventArgs e)
{
listingDataView.Filter -= new FilterEventHandler(ShowOnlyBargainsFilter);
}
private void ShowOnlyBargainsFilter(object sender, FilterEventArgs e)
{
AuctionItem product = e.Item as AuctionItem;
if (product != null)
{
//設置e.Accepted的值即可
e.Accepted = product.CurrentPrice < 25;
}
}

WPF中的數據綁定Data Binding使用小結