深入浅出WPF之Data Converter--笔记(2015.03.09)

Binding还有另外一种机制称为数据转换(Data Convert),当Source端Path所关联的数据与Target端目标属性数据类型不一致时,可以定义数据转换器(Data Converter)。当WPF不能自动转换数据类型时,只能自己写Converter,方法是创建一个类并让这个类实现IValueConverter接口。当数据从Binding的Source流向Target时,Convert方法将被调用;反之,ConvertBack方法将被调用。

    Binding对象的Mode属性会影响到这两个方法的调用。如果Mode为TwoWay或Default行为与TwoWay一致则两个方法都可能被调用;如果Mode为OneWay或Default行为与OneWay一致则只有Convert方法会被调用。事例如下:

XAML:

        <Window.Resources>
        <local:CategoryToSourceConverter x:Key="cts"/>
        <local:StateToNullablBoolConverter x:Key="stnb"/>
    </Window.Resources>
    <StackPanel Background="LightBlue">
        <ListBox x:Name="listBoxPlane" Height="160" Margin="5">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <Image Width="20" Height="20" Source="{Binding Path=Category, Converter={StaticResource ResourceKey=cts}}"/>
                        <TextBlock Text="{Binding Path=Name}" Width="60" Margin="80, 0"/>
                        <CheckBox IsThreeState="True" IsChecked="{Binding Path=State, Converter={StaticResource ResourceKey=stnb}}"/>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <Button x:Name="buttonLoad" Content="Load" Height="25" Margin="5, 0" Click="buttonLoad_Click"/>
        <Button x:Name="buttonSave" Content="Save" Height="25" Margin="5, 5" Click="buttonSave_Click"/>
    </StackPanel>

 

C#代码:

    public enum Category
    {
        Bomber,
        Fighter
    }

    public enum State
    {
        Available,
        Locked,
        Unknown
    }

    public class Plane
    {
        public Category Category { get; set; }
        public string Name { get; set; }
        public State State { get; set; }
    }

    public class CategoryToSourceConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            Category c = (Category)value;
            switch (c)
            {
                case Category.Bomber:
                    return @"\Icons\Bomber.png";
                case Category.Fighter:
                    return @"\Icons\Fighter.png";
                default:
                    return null;
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    public class StateToNullablBoolConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            State s = (State)value;
            switch (s)
            {
                case State.Available:
                    return true;
                case State.Locked:
                    return false;
                case State.Unknown:
                default:
                    return null;
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            bool? nb = (bool?)value;
            switch (nb)
            {
                case true:
                    return State.Available;
                case false:
                    return State.Locked;
                case null:
                default:
                    return State.Unknown;
            }
        }
    }

    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void buttonLoad_Click(object sender, RoutedEventArgs e)
        {
            List<Plane> planeList = new List<Plane>
            {
                new Plane{Category = Category.Bomber, Name = "B--1", State = State.Unknown},
                new Plane{Category = Category.Bomber, Name = "B--2", State = State.Unknown},
                new Plane{Category = Category.Fighter, Name = "F--22", State = State.Unknown},
                new Plane{Category = Category.Fighter, Name = "Su--47", State = State.Unknown},
                new Plane{Category = Category.Bomber, Name = "B--52", State = State.Unknown},
                new Plane{Category = Category.Fighter, Name = "J--10", State = State.Unknown}
            };
            this.listBoxPlane.ItemsSource = planeList;
        }

        private void buttonSave_Click(object sender, RoutedEventArgs e)
        {
            StringBuilder sb = new StringBuilder();
            foreach (Plane p in listBoxPlane.Items)
            {
                sb.AppendFormat(string.Format("Category = {0}, Name = {1}, State = {2}", p.Category, p.Name, p.State));
            }
            File.WriteAllText(@"D:\PlaneList.txt", sb.ToString());
        }
    }

 

你可能感兴趣的:(WPF,Data,Converter)