码迷,mamicode.com
首页 > 其他好文 > 详细

WPF之Binding对数据的转换(第五天)

时间:2014-07-16 22:48:23      阅读:229      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   os   文件   

Binding在Slider控件与TextBox控件之间建立关联,值可以互相绑定,但是它们的数据类型是不同的,Slider是Double类型,Text为String。原来,Binding有一种机制称为数据转换(Data Converter),当数据绑定的源与目标不同类型时,处理比较简单时,系统就自动的进行了类型转换,但是对于相对复杂的类型转换时,就需要我们手动进行了。

下面用一个例子来说明Convert的应用,程序的用途是在列表里面向玩家显示一些球的状态。

首先创建几个自定义数据类型:

public enum Category
    {
        Basketball,
        football
    }
    public enum State
    {
        Available,
        Locked,
        Unknown
    }
    public class ball
    {
        public Categroy Categroy { get;set; }
        public string Name { get; set; }
        public State State { get; set; }
    }

程序后面要用到的图片已经加载到程序中,球的State属性在UI里被映射为CheckBox。因为存在两个映射关系,我们需要提供两个Convert:一个是由Category类型单向转换为string,另一个State与bool?类型之间相互转换。代码如下:

public class CategoryToSourceConverter : IValueConverter
    {
        //将Category转换为Uri
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            Category c = (Category)value;
            switch (c)
            {
                case Category.Basketball:
                    return @"basketball.png";
                case Category.football:
                    return @"football.png";
                default:
                    return null;
            }
        }
        //不会被调用
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    public class StateToNullableBoolConvert : IValueConverter
    {
        //将state转换为bool?
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            State s = (State)value;
            switch (s)
            {
                case State.Locked:
                    return false;
                case State.Available:
                    return true;
                case State.Unknown:
                default:
                    return null;
            }
        }
        //将bool?转换为State
        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;
            }
        }
    }

下面我们看看如何在XAML里消费这些Converter。XAML代码的框架如下:

<Window x:Class="DataConverter.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:DataConverter"
        Title="MainWindow" Height="350" Width="525">
    
    <Window.Resources>
        <local:CategoryToSourceConverter x:Key="cts"/>
        <local:StateToNullableBoolConvert x:Key="stnb"/>
    </Window.Resources>
    <Grid>
        <StackPanel Background="LightBlue">
            <ListBox x:Name="listBoxPlan" Height="160" Margin="5,0"></ListBox>
            <Button x:Name="buttonLoad" Content="Load" Height="25" Margin="5,0"></Button>
            <Button x:Name="buttonSave" Content="Save" Height="25" Margin="5,5"></Button>            
        </StackPanel>
    </Grid>
</Window>

XAML代码中已经添加了对程序集的引用并映射为名称空间local,以资源的形式创建了两个Convert的实例。名为ListBoxPlan的ListBox控件需要为它添加用于显示数据的DataTemplate。我们把焦点集中在ListBox控件的ItemTemplate属性上:

<ListBox x:Name="listBoxPlan" Height="160" Margin="5,0">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <Image Width="20" Height="20"
                                   Source="{Binding Path=Category,Converter={StaticResource cts}}"></Image>
                            <TextBlock Text="{Binding Path=Name}" Width="60" Margin="80,0"/>
                            <CheckBox IsThreeState="True"
                                      IsChecked="{Binding Path=State,Converter={StaticResource stnb}}"/>
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>

Load按钮的Click事件处理负责把一组球的数据赋值给ListBox的ItemSource属性,Save按钮的Click事件处理器负责把用户更改过的数据写入文件:

//Load按钮Click事件处理器
        private void buttonLoad_Click(object sender, RoutedEventArgs e)
        {
            List<Ball> ballList = new List<Ball>()
            {
                new Ball(){Category = Category.Basketball,Name = "NBA",State = State.Unknown},
                new Ball(){Category = Category.Basketball,Name = "CBA",State = State.Unknown},
                new Ball(){Category = Category.football,Name = "世界杯",State = State.Unknown},
                new Ball(){Category = Category.football,Name = "欧冠",State = State.Unknown},
                new Ball(){Category = Category.Basketball,Name = "WNBA",State = State.Unknown},
                new Ball(){Category = Category.football,Name = "英超",State = State.Unknown}
            };
            this.listBoxPlan.ItemsSource = ballList;
        }
        //Save按钮Click事件处理器
        private void buttonSave_Click(object sender, RoutedEventArgs e)
        {
            StringBuilder sb = new StringBuilder();
            foreach (Ball b in listBoxPlan.Items)
            {
                sb.AppendLine(string.Format("Category={0},Name={1},State={2}", b.Category, b.Name, b.State));
            }
            File.WriteAllText(@"D:\BallList.txt", sb.ToString());
        }

运行程序并单击CheckBox更改State,效果图如下:

bubuko.com,布布扣

单击Save按钮后打开D:\BallList.txt:

bubuko.com,布布扣

注*读《深入浅出WPF》读书笔记

WPF之Binding对数据的转换(第五天),布布扣,bubuko.com

WPF之Binding对数据的转换(第五天)

标签:style   blog   http   color   os   文件   

原文地址:http://www.cnblogs.com/laoqi/p/3835688.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!