6.4.2 Binding的数据转换
当数据从Binding的Source流向Target时,Convert方法将被调用;反之,ConvertBack方法将被调用。
using System;
using System.Windows.Data;
using FirstWpfApplication.Objects;
namespace FirstWpfApplication.Converters
{
class CategoryToImageCoverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
Plane.CategoryEnum ct = (Plane.CategoryEnum)value;
switch (ct)
{
case(Plane.CategoryEnum.Bomber):
return @"\Images\bomber.png";
case (Plane.CategoryEnum.Fighter):
return @"\Images\fighter.png";
default:
return null;
}
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
using System;
using System.Windows.Data;
using FirstWpfApplication.Objects;
namespace FirstWpfApplication.Converters
{
class StateToNullableBooleanCoverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
Plane.StateEnum st = (Plane.StateEnum)value;
switch (st)
{
case Plane.StateEnum.Available:
return true;
case Plane.StateEnum.Locked:
return false;
default:
return null;
}
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
bool? state = value as bool?;
if (state == null)
return Plane.StateEnum.UnKnown;
else if (state.Value)
return Plane.StateEnum.Available;
else
return Plane.StateEnum.Locked;
}
}
}
namespace FirstWpfApplication.Objects
{
class Plane
{
public string Name { get; set; }
public CategoryEnum Category { get; set; }
public StateEnum State { get; set; }
public enum CategoryEnum
{
Bomber,
Fighter
}
public enum StateEnum
{
Available,
Locked,
UnKnown
}
}
}
<Window x:Class="FirstWpfApplication.MainWindow"
x:ClassModifier="public"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:data="clr-namespace:System.Windows.Data;assembly=PresentationFramework"
xmlns:local="clr-namespace:FirstWpfApplication"
xmlns:converter="clr-namespace:FirstWpfApplication.Converters"
Title="登录" Height="250" Width="200" >
<Window.Resources>
<converter:CategoryToImageCoverter x:Key="ctic"/>
<converter:StateToNullableBooleanCoverter x:Key="stnbc"/>
</Window.Resources>
<Grid x:Name="g1" Background="Orange" Margin="5">
<Grid.RowDefinitions>
<RowDefinition Height="120" />
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
</Grid.RowDefinitions>
<ListBox x:Name="planeListBox" Grid.Row="0" Margin="5">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<!--[ˌɔ:rienˈteiʃən] 方向 定位-->
<Image Width="40" Height="20" Source="{Binding Path=Category, Converter={StaticResource ResourceKey=ctic}}"/>
<TextBlock Width="80" Height="20" Text="{Binding Path=Name}"/>
<CheckBox Width="40" Height="20" IsThreeState="True" IsChecked="{Binding Path=State, Converter={StaticResource ResourceKey=stnbc}}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button Content="Load" x:Name="buttonLoad" Grid.Row="1" Width="60" Height="25" Click="buttonLoad_Click"/>
<Button Content="Save" x:Name="buttonSave" Grid.Row="2" Width="60" Height="25" Click="buttonSave_Click"/>
</Grid>
</Window>
private void buttonLoad_Click(object sender, RoutedEventArgs e)
{
List<Plane> planes = new List<Plane>()
{
new Plane(){Name="J-10", Category=Plane.CategoryEnum.Fighter, State=Plane.StateEnum.Available},
new Plane(){Name="H-6", Category=Plane.CategoryEnum.Bomber, State=Plane.StateEnum.Available},
new Plane(){Name="F-22", Category=Plane.CategoryEnum.Fighter, State=Plane.StateEnum.Locked},
new Plane(){Name="B-2", Category=Plane.CategoryEnum.Bomber, State=Plane.StateEnum.UnKnown}
};
this.planeListBox.ItemsSource = planes;
}
private void buttonSave_Click(object sender, RoutedEventArgs e)
{
StringBuilder sb = new StringBuilder();
foreach (Plane p in planeListBox.Items)
sb.AppendLine(string.Format("Category={0},Name={1},State={2}", p.Category, p.Name, p.State));
File.WriteAllText(@"D:\PlaneList.txt", sb.ToString());
}
Provide value on 'System.Windows.Markup.StaticResourceHolder' threw an excep
产生这个错误的原因是,StaticResource必须先定义再引用,但是DynamicResource就没有这个限制,为避免这个错误出现,可将StaticResource的定义放在Window.xaml的最前端,或者放在App.xaml中.