WPF笔记

1、使用TypeConvert类将XAML标签的Attribute与对象的Propety进行映射

由于XAML所有属性=属性值,其中属性值必须是字符串,当属性值不是字符串时需要添加将该属性值转换成字符串的转换器,如下Human类child的Human类情况

<Window x:Class="WPF.TypeConvertFromProperty"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:Entity="clr-namespace:Entity;assembly=Entity"
        Title="TypeConvertFromProperty" Height="300" Width="300">
    <Window.Resources>
        <Entity:Human x:Key="human" Child="ABC"/>
    </Window.Resources> 
</Window>
[TypeConverter(typeof(StringToHumanTypeConverter))]
    public class Human
    {
        public string Name { get; set; }
        public Human Child { get; set; }
    }


    public class StringToHumanTypeConverter : TypeConverter
    {
        public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
        {
            if (value is string)
            {
                Human h = new Human();
                h.Name = value as string;
                return h;
            }
            return base.ConvertFrom(context, culture, value);
        }
    }

2、x:Attribute

①x:Class

告诉编译器xaml标签的编译结果与后台代码中指定的类合并

②x:ClassModifier

由标签生成的类的访问控制级别,如internal,public,private

③x:FieldModifier

标签的访问控制级别,如<TextBox x:Name="textbox"  x:FieldModifier="public"/>

④x:Share

 3、布局

主要布局控件有:Grid,StackPanel,Cavas DockPanel,WrapPanel

4、Binding对数据的校验

<Window x:Class="WPF.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:Entity="clr-namespace:Entity;assembly=Entity"
        Title="MainWindow" Height="350" Width="525">
    
    <StackPanel>
        <TextBox x:Name="textbox1" Margin="5"/>
        <Slider x:Name="slider1" Minimum="0" Maximum="100" Margin="5"/>
    </StackPanel>
</Window>
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;

namespace WPF
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            Binding binding = new Binding("Value") {Source=this.slider1 };
            binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
            RangeValidationRule rvr = new RangeValidationRule();
            rvr.ValidatesOnTargetUpdated = true;//设置Source出错时也校验,Binding只有在Target被外部方法改变时才校验
            binding.ValidationRules.Add(rvr);//添加校验
            binding.NotifyOnValidationError = true;//设置校验失败时Binding发出一个信号

            this.textbox1.SetBinding(TextBox.TextProperty, binding);
            this.textbox1.AddHandler(Validation.ErrorEvent,new RoutedEventHandler(this.ValidationErro));//添加侦听校验处理事件
        }


        //侦听校验处理事件
        private void ValidationErro(object sender, RoutedEventArgs e)
        {
          if(Validation.GetErrors(this.textbox1).Count>0)
          {
              this.textbox1.ToolTip = Validation.GetErrors(this.textbox1)[0].ErrorContent.ToString();
          }
        }

    }



    /// <summary>
    /// 校验类
    /// </summary>
    public class RangeValidationRule : ValidationRule
    {
        public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
        {
            double d = 0;
            if(double.TryParse(value.ToString(),out d))
            {
                if(d>0&&d<100)
                {
                    return new ValidationResult(true, null);
                }
            }
            return new ValidationResult(false, "validation fail");
        }
    }
}

5、Binding对数据的转换

 当Source里的数据是X,Y,N时,UI上对应的是CheckBox控件的IsChecked属性值时此时我们需要手动写一个Converter类(称为数据转换器)来转换,方法是创建一个类并让这个类实现IValueConverter接口。此时当数据从Binding的Source流向target时,Convert方法被调用,反之ConvertBack方法被调用

using System;


namespace WPF.Entity
{
    class Plane
    {
        public Category Category { get; set; }

        public State State { get; set; }

        public string Name { get; set; }

    }


    public enum Category
    {
        Bomber,
        Figher
    }

    public enum State
    {
        Available,
        Locked,
        Unknown
    }
}

using System;
using System.Windows.Data;
namespace WPF.Entity
{
    /// <summary>
    /// Category数据转换器
    /// </summary>
    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 @"IconsBomber.jpg";
                case Category.Figher:
                    return @"IconsFligter.jpg";
                default:
                    return null;
            }
        }

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


    /// <summary>
    /// State数据转换器
    /// </summary>
    public class StateToNullableBool: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? b = (bool?)value;
            switch (b)
            {
                case true:
                    return State.Available;
                case false:
                    return State.Locked;
                case null:
                default:
                    return State.Unknown;
            }
        }
    }
}
<Window x:Class="WPF.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:LocalEntity="clr-namespace:WPF.Entity"
        Title="MainWindow" Height="350" Width="800">
    <Window.Resources>
        <LocalEntity:CategoryToSourceConverter x:Key="cts"/>
        <LocalEntity:StateToNullableBool x:Key="stab"/>
    </Window.Resources>
    <StackPanel>
        <ListBox x:Name="listboxPlane" Height="160" Margin="5">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <Image Width="20" Height="20" Source="{Binding Path=Category,Converter={StaticResource cts}}"/><!--数据转换器以静态资源进行引用-->
                        <TextBlock Text="{Binding Name}" Width="60" Margin="80,0"/>
                        <CheckBox IsThreeState="True" IsChecked="{Binding Path=State,Converter={StaticResource stab}}"/>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <Button x:Name="btnLoad" Content="Load" Height="25" Margin="5,0" Click="btnLoad_Click"/>
        <Button x:Name="btnSave" Content="Save" Height="25" Margin="5,5" Click="btnSave_Click"/>
    </StackPanel>
</Window>
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using WPF.Entity;
using System;

namespace WPF
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
           
        }


        /// <summary>
        /// Load按钮事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnLoad_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.Figher,Name="F-22",State=State.Unknown},
                new Plane(){Category=Category.Figher,Name="F-Su47",State=State.Unknown},
                new Plane(){Category=Category.Bomber,Name="B-52",State=State.Unknown},
                new Plane(){Category=Category.Figher,Name="F-J10",State=State.Unknown},
            };
            this.listboxPlane.ItemsSource = planeList;
        }


       /// <summary>
       /// 保存按钮事件
       /// </summary>
       /// <param name="sender"></param>
       /// <param name="e"></param>
        private void btnSave_Click(object sender, RoutedEventArgs e)
        {
            StringBuilder sb = new StringBuilder();
            foreach (Plane p in listboxPlane.Items)
            {
                sb.AppendLine(string.Format("Category={0},Name={1},State={2}",p.Category,p.Name,p.State));
            }
            string filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"PlaneList.txt");
            File.WriteAllText(filePath,sb.ToString());
        }

    }
}
原文地址:https://www.cnblogs.com/come-on-come-on/p/5392557.html