WPF框架 QuickStart 数据绑定及附加属性

WPF QuickStart数据绑定(Data Binding)

首先看一下WPF Data Binding的概览,

Binding Source可以是任意的CLR对象,或者XML文件等,Binding Target需要有依赖属性。这样便可以进行Data Binding。请看下面的示例,

C#

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new Person() { Name = "Tom", Age = 25 };
    }
}
public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

XAML:

<Grid>
    <StackPanel>
        <TextBlock Text="{Binding Name}" Margin="10,5"/>
        <TextBlock Text="{Binding Age}" Margin="10,5"/>
    </StackPanel>
</Grid>

运行结果:

下面通过一些例子来介绍在Data Binding,

1. 我们可以在XAML中,指定Binding Target的ElementName和Path属性来获取Binding Source的数据,例如,

XAML:

<StackPanel>
    <Slider x:Name="_slider" Minimum="0" Maximum="100" Value="20"/>
    <TextBox Text="{Binding ElementName=_slider,Path=Value}"/>
</StackPanel>

运行结果:

上面XAML代码中,将Slider的Value属性Binding到TextBox。

通过上面的Gif图片可以发现,当拖动Slider时,TextBox框中的数值随着Slider的Value改变而改变,当在TextBox中输入数值时,按Tab键失去焦点后,Slider的Value发生了改变。这是因为TextBox的默认Binding Mode为TwoWay,且UpdateSoureTrigger默认为LostFocus。请看下面的BindingMode示意图,

图示中有种Binding Mode,

OneWay,数据流向是从Source到Target;

TwoWay,数据可以从Source到Target,也可以从Target到Source,

OneWayToSource与OneWay相反,

OneTime,表示数据绑定发生后,数据源无论如何改变,Target中绑定的值都不会发生改变。

下面我们通过例子来演示这4种绑定

XAML:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <!--OneWay Binding-->
    <StackPanel>
        <TextBlock Text="Binding Mode: OneWay"/>
        <Slider x:Name="_slider" Minimum="0" Maximum="100" Value="20"/>
        <TextBox Text="{Binding ElementName=_slider,Path=Value,Mode=OneWay}"/>
    </StackPanel>
    
    <!--OneTime Binding-->
    <StackPanel Grid.Row="1" Margin="0,20">
        <TextBlock Text="Binding Mode: OneTime"/>
        <Slider x:Name="_slider1" Minimum="0" Maximum="100" Value="20"/>
        <TextBox Text="{Binding ElementName=_slider1,Path=Value,Mode=OneTime}"/>
    </StackPanel>
    
    <!--OneWayToSource Binding-->
    <!--将TextBox的FontSize默认值为12-->
    <StackPanel Grid.Row="2">
        <TextBlock Text="Binding Mode: OneWayToSource"/>
        <Slider x:Name="_slider2" Minimum="0" Maximum="100" Value="20"/>
        <TextBox FontSize="{Binding ElementName=_slider2,Path=Value, Mode=OneWayToSource}" 
                 Text="{Binding RelativeSource={RelativeSource Self},Path=FontSize}"/>
    </StackPanel>
    <!--TwoWay Binding-->
    <StackPanel Grid.Row="3" Margin="0,20">
        <TextBlock Text="Binding Mode: TwoWay"/>
        <Slider x:Name="_slider3" Minimum="0" Maximum="100" Value="20"/>
        <TextBox Text="{Binding ElementName=_slider3,Path=Value,Mode=TwoWay}"/>
    </StackPanel>
</Grid>

运行结果:

在项目开发中根据实际需要选择不同的Binding Mode,如果某些数据只在程序启动时显示,后面对数据进行修改了,不需要更新,可以选择OneTime Mode;如果对数据进行实时展示,可以选择OneWay Mode;如果需要将数据的修改同步,那么我们选择TwoWay Mode。合适的绑定模式可以最优化程序的性能。

接下来看UpdateSourceTrigger,UpdateSourceTrigger有下面几种取值,

1. LostFocus, 例如TextBox失去焦点后更新Source;
2. PropertyChanged,例如当在TextBox中输入时,Source便同步更新;
3. Explict,需要显示的调用UpdateSource方法;

下面我们看Binding中另一个概念Converter;看这样一个例子,有一个文本框显示当前温度,如果温度大于35,则将文本框的前景色设置为红色,如果温度小于0,则显示为蓝色;

XAML:

<Window.Resources>
    <local:TemperatureToBrushCoverter Hot="35" Cold="0" x:Key="TemperatureToBrushCoverter"/>
</Window.Resources>
<Grid>
    <TextBox Text="30" Width="200" Height="25"
                 Foreground="{Binding Path=Text,RelativeSource={RelativeSource Self},
                 Converter={StaticResource TemperatureToBrushCoverter}}"/>
</Grid>

C#:

[ValueConversion(typeof(double),typeof(Brush))]
public class TemperatureToBrushCoverter : IValueConverter
{
    public double Hot { get; set; }
    public double Cold { get; set; }
    public TemperatureToBrushCoverter()
    {
    }
    public TemperatureToBrushCoverter(double hot,double cold)
        :this()
    {
        Hot = hot;
        Cold = cold;
    }
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        double temp;
        Brush brush = Brushes.Black;
        if(Double.TryParse((string)value,out temp))
        {
            if(temp > Hot)
            {
                brush = Brushes.Red;
            }
            else if(temp < Cold)
            {
                brush = Brushes.Blue;
            }
        }
        return brush;
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

运行结果:

注意要在XAML中引用Converter。

最后我们看一下DataBinding中的数据验证;来看这样一个例子,将Person对象的Age绑定到一个TextBox上,并可以对Age进行修改,年龄是一个有实际意义的值,如果Age小于0或者大于120,我们均认为其为非法值,给出相应提示。请看下面的代码:

XAML:

<Grid>
    <TextBox Width="200" Height="25">
        <TextBox.Text>
            <Binding Path="Age" UpdateSourceTrigger="PropertyChanged">
                <Binding.ValidationRules>
                    <local:AgeValidationRule ValidationStep="RawProposedValue"/>
                </Binding.ValidationRules>
            </Binding>
        </TextBox.Text>
        <!--Error Template-->
        <Validation.ErrorTemplate>
            <ControlTemplate>
                <StackPanel>
                    <AdornedElementPlaceholder/>
                    <TextBlock Text="{Binding [0].ErrorContent}" Foreground="Red"/>
                </StackPanel>
            </ControlTemplate>
        </Validation.ErrorTemplate>
    </TextBox>
</Grid>

C#:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new Person() { Age = 25};
    }
}
public class Person
{
    public int Age { get; set; }
}
public class AgeValidationRule : ValidationRule
{
    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        int age;
        if(int.TryParse((string)value,out age))
        {
            if(age< 0 || age > 120)
            {
                return new ValidationResult(false, "This is invalide age.");
            }
            else
            {
                return new ValidationResult(true, null);
            }
        }
        return new ValidationResult(false, "Please input valid age.");
    }
}

运行结果:

WPF QuickStart 附加属性(Attached Property)

1. 附加属性使用,

WPF中对附加属性使用最多的莫过于对控件布局时设置控件的位置,例如在Canvas中有一个Rectangle, Ellipse, Button,我们需要设置它们的位置,

<Canvas>
    <Rectangle x:Name="_rect" Fill="LightBlue" Width="100" Height="50" Canvas.Left="200" Canvas.Top="50"/>
    
    <Ellipse Width="100" Height="100" Fill="LightCoral" Canvas.Left="150" Canvas.Top="200"/>
    
    <Button Content="I am a button" Width="100" Height="35" Canvas.Left="50" Canvas.Bottom="50"/>
</Canvas>

除了在XAML中设置依赖属性外,也可以在C#代码中设置,例如:

   Canvas.SetLeft(_rect, 100);
   Canvas.SetTop(_rect, 50);

显示效果:

附加属性使用起来非常简单。

2. 自定义附加属性

现在有这样一个需求,需要将上面的Button,Ellipse,Rectangle旋转一定角度。我们可以这样来实现:

XAML:

<Canvas>
    <Rectangle x:Name="_rect" Fill="LightBlue" Width="100" Height="50" Canvas.Top="100" RenderTransformOrigin=".5,.5">
        <Rectangle.RenderTransform>
            <RotateTransform Angle="45"/>
        </Rectangle.RenderTransform>
    </Rectangle>
    <Ellipse Width="150" Height="100" Fill="LightCoral" Canvas.Left="150" Canvas.Top="100" RenderTransformOrigin=".5,.5">
        <Ellipse.RenderTransform>
            <RotateTransform Angle="60"/>
        </Ellipse.RenderTransform>
    </Ellipse>
    <Button Content="I am a button" Width="100" Height="35" Canvas.Left="50" Canvas.Bottom="50" RenderTransformOrigin=".5,.5">
        <Button.RenderTransform>
            <RotateTransform Angle="160"/>
        </Button.RenderTransform>
    </Button>
</Canvas>

效果如下:

细心的你已经发现上面的三段代码基本一样,而且还挺长的。我们可以使用附加属性来实现,新建一个RotationHelper类,代码如下:

using System.Windows;
using System.Windows.Media;
namespace UseAttachedProperty.Helper
{
    public class RotationHelper : DependencyObject
    {
        public static double GetAngle(DependencyObject obj)
        {
            return (double)obj.GetValue(AngleProperty);
        }
        public static void SetAngle(DependencyObject obj, double value)
        {
            obj.SetValue(AngleProperty, value);
        }
        public static readonly DependencyProperty AngleProperty =
            DependencyProperty.RegisterAttached("AngleProperty", typeof(double), typeof(RotationHelper), 
                new PropertyMetadata(0.0,OnAngleChanged));
        private static void OnAngleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            UIElement element = d as UIElement;
            if(element != null)
            {
                element.RenderTransformOrigin = new Point(0.5, 0.5);
                element.RenderTransform = new RotateTransform((double)e.NewValue);
            }
        }
    }
}

将RotationHelper类继承DependencyObject,这样不光Button,Ellipse,可以使用,其他继承自DependencyObject的元素均可使用。

现在在XAML中使用自定义Angle附加属性。

<Window x:Class="UseAttachedProperty.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:helper="clr-namespace:UseAttachedProperty.Helper"
        xmlns:local="clr-namespace:UseAttachedProperty"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Canvas>
        <Rectangle x:Name="_rect" Fill="LightBlue" Width="100" Height="50" Canvas.Top="100" helper:RotationHelper.Angle="45" />
        <Ellipse Width="150" Height="100" Fill="LightCoral" Canvas.Left="150" Canvas.Top="100" helper:RotationHelper.Angle="60" />
        <Button Content="I am a button" Width="100" Height="35" Canvas.Left="50" Canvas.Bottom="50" helper:RotationHelper.Angle="160" />
    </Canvas>
</Window>

此时显示效果和上面通过XAML中使用RenderTransform一样。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索c#
, 数据
, textbox
, 属性
, binding
data
maven quickstart、maven quickstart项目、cloudera quickstart、quickstart、quick start,以便于您获取更多的相关知识。

时间: 2025-01-21 10:30:22

WPF框架 QuickStart 数据绑定及附加属性的相关文章

WPF学习之数据绑定

WPF中的数据绑定提供了很强大的功能.与普通的WinForm程序相比,其绑定功能为我们提供了很多便利,例如Binding对象的自动通知/刷新,Converter,Validation Rules,Two Way Binding等功能,省去了很多维护的繁琐工作.另外对于WPF中提供的数据模板功能,让我们可以轻松定制可以被复用的控制呈现的模块-但这是以数据绑定为前提来做到轻松易用的效果的.数据提供者例如XmlDataProvider和ObjectDataProvider更是简化了将对象以特定方式绑定

WPF框架的内存泄漏BUG

用户在使用GIX4某模块的过程中,内存只见加不见减.我们怀疑出现了内存泄漏,所以我花了相当一 段时间来进行此问题的排查. 我使用Red Gate公司的产品ANTS Memory Profiler 5进行应用程序的内存进行监视.并在过程中修改 程序中出现的一些问题.但是最后留下一个不知道原因的引用,如图1: 图1 泄漏对象引用图 由图中可以看出,Application.Resources永久地引用了临时控件SelectionDataGrid.原因出在 DeferredAppResourceRefe

WPF框架实现微信公众号多客服实例教程(多图)

利用WPF框架作为前端技术,实现桌面版微信多客服系统.项目采用Prism作为前端框架,采用MVVM模式极好的对UI和逻辑代码分离,使用MefBootstrapper集成的MEF IOC容器,解耦各模块对象.合理利用 IEventAggregator 实现事件和交互.文章在介绍对应功能时候会给出相关实现的参考,读者可以参考改进,引入到自己的项目中. 程序运行界面及功能预览: 一.登陆: 功能:支持记住用户和用户设置,可选择记住用户密码. 实现相关: 自定义登陆窗口,引入Microsoft.Wind

C#,wpf框架,点击之后数据库的值返回到窗口中的datagrid上显示,不能返回结果

问题描述 C#,wpf框架,点击之后数据库的值返回到窗口中的datagrid上显示,不能返回结果 private void button5_Click(object sender, RoutedEventArgs e) { //this.Hide(); // MessageBox.Show("登陆成功!!!"); string constr = "server=PC-20150723QMEF;database=dhj;integrated security=SSPI"

WPF中的数据绑定

目录 数据绑定细节 创建简单的绑定 绑定模式 绑定的 时间 绑定到 XML 对象绑定和 DataTemplates 对数据进行排 序 欢迎试用和反馈 到目前为止,很多人都知道使用 Windows Presentation Foundation (WPF) 可以轻松地设计强大的用户界面.但是您可能 并不知道它还提供了强大的数据绑定功能.使用 WPF,可以通过利用 Microsoft .NET Framework 代码.XAML 或两者的组合进行数据操作.您可 以绑定控件.公共属性.XML 或对象,

WPF框架自定义windows Metro Style窗体教程

先看一下最终窗体的效果图, 通过截图我们可以看出来这个窗体由两部分组成,顶部为最小化和关闭按钮,其他区域为窗体的显示区域.请看下面的具体实现代码, MetroWindow样式: <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"                     xmlns:x="http://schemas.microsoft.com/winf

WPF框架中使用CefSharp嵌入web浏览器的方法教程

首先先介绍一下CefSharp嵌入式浏览器,它是基于Google浏览器的一个组件,我们可以在WPF/WinForm客户端软件中使用它.CefSharp的代码托管在GitHub上,.NET (WPF and Windows Forms) bindings for the Chromium Embedded Framework. 目前最新版本的CefSharp是41.0版本,如果你的客户端软件需要支持WIN XP操作系统,建议使用CefSharp.Wpf 1.25.7及之前的版本.可以从Nuget上

WPF and Silverlight学习笔记(二十):WPF数据绑定概述

WPF数据绑定为应用程序提供了一种表示数据和与数据交互的简单而又一致的 方法.元素能够以公共语言运行库 (CLR) 对象和 XML 的形式绑定到各种数据源 中的数据. 一.数据绑定的基本概念: 数据绑定涉及到两个方面 :一个是绑定源,再一个是绑定目标.绑定源即控件绑定所使用的源数据,绑定 目标即数据显示的控件. 1.对于绑定源,在WPF可以是以下四种: CLR对象:可以绑定到CLR类的公开的属性.子属性.索引器上 ADO.Net对象:例如DataTable.DataView等 XML文件:使用X

使用数据绑定和WPF自定义数据显示

本文将介绍以下内容: WPF 数据绑定 数据显示和分层数据 使用模板 输入验证 本文使用以下技术: WPF. XAML.C# 目录 在代码中绑定 使用模板 使用继承的 DataContext 使用集合视图 使用分层数据 使用多个控件显示 XML 数据 使用多个控件显示业务对象 一个用于显示整个层次结构的控件 使 用分层数据模板 使用用户输入 通过 ValidationRules 验证输入 显示验证错误 通过 IDataErrorInfo 验证输入 结束语 在虚拟实验室中进行试验: 当 Windo