精华内容
下载资源
问答
  • wpf模板绑定实例属性
    2013-10-13 12:07:00
      <Style  TargetType="{x:Type TabItem}" x:Key="EditorTabItemStyle">
            <Setter  Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type TabItem}">
                        <Border x:Name="layout" BorderBrush="Gray" BorderThickness="1,1,1,0" Background="{TemplateBinding Background}"
                                    CornerRadius="3" Margin="2,0,2,0">
                            <Grid Height="20">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition/>
                                    <ColumnDefinition Width="25"/>
                                </Grid.ColumnDefinitions>
                                <TextBlock TextAlignment="Center" Text="{TemplateBinding Header}" ToolTip="{TemplateBinding ToolTip}" Tag="{TemplateBinding Tag}" Grid.Column="0" Margin="4,0,3,0"
                                VerticalAlignment="Center" HorizontalAlignment="Center">
                                    <TextBlock.ContextMenu>
                                        <ContextMenu DataContext="{TemplateBinding Tag}">
                                            <MenuItem Header="保存"  Click="Save_Command" IsEnabled="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type ContextMenu},AncestorLevel=1},Path=DataContext}" >
                                            </MenuItem>
                                            <MenuItem Header="关闭"  Click="Close_Command">
                                            </MenuItem>
                                        </ContextMenu>
                                    </TextBlock.ContextMenu>
                                </TextBlock>
                                <Button Content="X" Grid.Column="1"  Height="8" Width="8" Margin="4,1,3,2" 
                                Tag="{TemplateBinding Header}" 
                                Click="Button_Click"
                                Background="{x:Null}" BorderBrush="{x:Null}" VerticalAlignment="Center">
                                    <Button.Template>
                                        <ControlTemplate >
                                            <Grid>
                                                <Rectangle>
                                                    <Rectangle.Fill>
                                                        <VisualBrush>
                                                            <VisualBrush.Visual>
                                                                <Path x:Name="btnPath" 
                                                            Data="M0 0L10 10M0 10L10 0" Stroke="Gray"
                                                            StrokeThickness="1"/>
                                                            </VisualBrush.Visual>
                                                        </VisualBrush>
                                                    </Rectangle.Fill>
                                                </Rectangle>
                                            </Grid>
                                            <ControlTemplate.Triggers>
                                                <Trigger Property="IsMouseOver" Value="True">
                                                    <Setter TargetName="btnPath" Property="Stroke" Value="Red"/>
                                                </Trigger>
                                            </ControlTemplate.Triggers>
                                        </ControlTemplate>
                                    </Button.Template>
                                </Button>
                            </Grid>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsSelected" Value="True">
                                <Setter Property="Background" Value="White"/>
                                <Setter TargetName="layout" Property="Margin" Value="2,0,2,-1.5"/>
                            </Trigger>
                            <Trigger Property="IsSelected" Value="false">
                                <Setter Property="Background" Value="LightBlue"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

     

    上面实例代码展示如何将tabitem中的字段绑定到menuitem上,先通过TemplateBinding获取属性值赋值到DataContext属性,然后再通过指定的控件类型和第几个来绑定

    IsEnabled="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type ContextMenu},AncestorLevel=1},Path=DataContext}" >

    具体说明可以参考:

    http://www.cnblogs.com/lzhp/archive/2012/09/11/2673810.html

    中的2.9的说明

     

     

    更多相关内容
  • WPF数据绑定

    千次阅读 2022-04-20 08:30:27
    一、概念:什么是数据绑定WPF中的数据绑定:是在应用程序 UI 与业务逻辑之间建立连接的过程; 扩展: 1.为应用程序提供了一种表示数据和与数据交互的...在 WPF 中,元素的依赖项属性可以绑定到 CLR 对象(包括 ADO.

    一、概念:什么是数据绑定?
    WPF中的数据绑定:是在应用程序 UI 与业务逻辑之间建立连接的过程;
    扩展:

    1.为应用程序提供了一种表示数据和与数据交互的简单而又一致的方法。
    2.元素能够以公共语言运行时 (CLR) 对象和 XML 的形式绑定到各种数据源中的数据。
    3.数据绑定可能还意味着如果元素中数据的外部表现形式发生更改,则基础数据可以自动更新以反映更改。
    4.一种典型用法是将服务器或本地配置数据放置到窗体或其他 UI 控件中。在 WPF 中,元素的依赖项属性可以绑定到 CLR 对象(包括 ADO.NET 对象或与 Web 服务和 Web 属性相关联的对象)和 XML 数据XmlNode。

    二、具体概念定义:
    基础模型:在这里插入图片描述
    如上图所示,数据绑定实质上是绑定目标与绑定源之间的桥梁。

    每个绑定的四个组件:绑定目标对象、目标属性(依赖项属性)、绑定源、绑定源值路径每个绑定的四个组件:绑定目标对象、目标属性(依赖项属性)、绑定源、绑定源值路径

    数据流的方向
    在这里插入图片描述

    OneWay:绑定导致对源属性的更改会自动更新目标属性,但是对目标属性的更改不会传播回源属性。

    1. 适用于绑定的控件为隐式只读控件的情况。
    2. 可避免 TwoWay 绑定模式的系统开销

    TwoWay:绑定导致对源属性的更改会自动更新目标属性,而对目标属性的更改也会自动更新源属性。

    1. 此绑定类型适用于可编辑窗体或其他完全交互式 UI 方案。

    OneWayToSource 与 OneWay 绑定相反。

    1. 一个示例方案是您只需要从 UI 重新计算源值的情况。

    OneTime 绑定未在图中显示,该绑定会导致源属性初始化目标属性,但不传播后续更改。

    1. 使用当前状态的快照适合使用的或数据状态实际为静态的数据。
    2. 如果要从源属性初始化具有某个值的目标属性,并且事先不知道数据上下文,则也可以使用此绑定类型。
    3. 此绑定类型实质上是 OneWay 绑定的简化形式,在源值不更改的情况下可以提供更好的性能。

    扩展:

    1. 查看绑定方向:使用 GetMetadata 获取属性的属性元数据,然后检查 BindsTwoWayByDefault 属性的布尔值。
    2. 若要检测源更改(适用于 OneWay 和 TwoWay 绑定),则源必须实现一种合适的属性更改通知机制(如 INotifyPropertyChanged)

    触发源的更新情况
    绑定的 UpdateSourceTrigger 属性确定触发源更新的原因。
    在这里插入图片描述
    下表使用 TextBox 作为示例提供每个 UpdateSourceTrigger 值的示例方案:
    在这里插入图片描述

    三、创建绑定
    指定绑定源
    在元素上直接设置 DataContext 属性、从上级继承 DataContext 值(如第一个示例中的按钮)、
    通过设置 Binding 上的 Source 属性来显式指定绑定源(如最后一个示例中的按钮),
    还可以使用 ElementName 属性或 RelativeSource 属性指定绑定源。
    指定值的路径
    如果绑定源是一个对象,则可使用 Path 属性指定要用于绑定的值。
    如果要绑定到 XML 数据,则可使用 XPath 属性指定该值。
    在某些情况下,可以使用 Path 属性,即使在数据为 XML 时。 例如,如果要访问返回的 XmlNode(作为 XPath 查询的结果)的 Name 属性,则应使用 Path 属性和 XPath 属性。
    Binding和BindingExpression
    Binding 类是用于绑定声明的高级别类;
    相关类 BindingExpression 是维持源与目标之间的连接的基础对象。
    BindingExpression 是无法共享的实例表达式,其中包含有关 Binding 的所有实例信息。
    可以通过对数据绑定对象调用 GetBindingExpression 的返回值来获取 BindingExpression 对象。
    四、数据转换
    在这里插入图片描述

    通过实现 IValueConverter 接口来创建一个自定义转换器,在这些方案中,实现数据转换器是非常有意义的:

    数据应根据区域性以不同方式显示。 例如,可能需要根据在特定区域性中使用的值或标准,来实现货币转换器或日历日期/时间转换器。
    使用的数据不一定会更改属性的文本值,但会更改其他某个值(如图像的源,或显示文本的颜色或样式)。 在这种情况下,可以通过转换可能不合适的属性绑定(如将文本字段绑定到表单元格的 Background 属性)来使用转换器。
    将多个控件或控件的多个属性绑定到相同数据。 在这种情况下,主绑定可能仅显示文本,而其他绑定则处理特定的显示问题,但仍使用同一绑定作为源信息。
    对于 MultiBinding,可以使用自定义 IMultiValueConverter 从绑定的值生成最终值。 例如,可以从红色、蓝色和绿色的值来计算颜色,这些值可以是来自于相同或不同绑定源对象的值。
    五、绑定到集合
    绑定到数据集合是一个常见方案。 例如,一个常见方案是使用 ItemsControl(如 ListBox、 ListView 或 TreeView)来显示数据集合。
    在这里插入图片描述

    如何实现集合
    WPF 提供 ObservableCollection 类,它是公开 INotifyCollectionChanged 接口的数据集合的内置实现。
    如果您有高级方案并且希望实现自己的集合,请考虑使用 IList,它提供可以按索引逐个访问的对象的非泛型集合,因而可提供最佳性能。
    集合视图

    一旦 ItemsControl 绑定到数据集合,您可能希望对数据进行排序、筛选或分组。 若要执行此操作,可以使用集合视图,这是实现
    ICollectionView 接口的类。

    什么是集合视图

    集合视图是位于绑定源集合顶部的一层,您可以通过它使用排序、筛选和分组查询来导航和显示源集合,而无需更改基础源集合本身。

    ps:通过使用视图,可以通过多种不同的方式来显示相同数据。
    例如,您可能希望在页面左侧显示按优先级排序的任务,而在页面右侧显示按区域分组的任务。

    如何创建视图

    创建和使用视图的一种方式是直接实例化视图对象并将其用作绑定源。

    CollectionViewSource 类是继承自 CollectionView 的类的XAML代理。 视图的 Source
    绑定到当前应用程序对象的 类型为 ObservableCollection集合 。 若要为同一集合创建另一个视图,可以创建另一个
    CollectionViewSource 实例并为其提供另一个 x:Key 名称。

    在这里插入图片描述

    使用默认视图

    一个绑定控件或代码对默认视图所做的更改(如排序或对当前项指针的更改,下文将对此进行讨论)会反映在到同一集合的所有其他绑定中。

    包含ADO.NET数据表的集合视图
    为了提高性能,ADO.NET DataTable 或 DataView 对象的集合视图会将排序和筛选工作委托给 DataView。 这会导致排序和筛选工作由数据源的所有集合视图分担。
    若要使每个集合视图都能独立进行排序和筛选,请用每个集合视图自己的 DataView 对象来初始化它。
    排序
    通过使用视图,可以应用这种用户驱动的排序,而无需对基础集合进行任何更改,甚至不必再次查询集合内容。 有关示例,请参见 如何:在单击标题时对 GridView 列进行排序。

    listingDataView.SortDescriptions.Add(
            new SortDescription("Category", ListSortDirection.Ascending));
    

    筛选
    视图还可以将筛选器应用于集合。

    listingDataView.Filter += new FilterEventHandler(ShowOnlyBargainsFilter);
    

    如果直接使用一个 CollectionView 类而不是 CollectionViewSource,则应使用 Filter 属性来指定回调。

    分组
    所有的集合视图都支持分组功能,用户可以利用此功能将集合视图中的集合划分成逻辑组。

    当前项指针
    由于 WPF 只通过使用视图(您指定的视图或集合的默认视图)绑定到集合,因此到集合的所有绑定都有一个当前项指针。 绑定到视图时,Path 值中的斜杠(“/”)字符用于指定视图的当前项。
    当前项指针可能会受对集合应用的任何排序或筛选操作的影响。
    主-从绑定方案
    通过将两个或更多控件绑定到同一视图可以轻松地实现主-从方案。
    六、数据模板化
    见后续一章详述
    七、数据验证
    将验证规则与绑定关联
    使用 WPF 数据绑定模型可以将 ValidationRules 与 Binding 对象相关联。
    ValidationRule 对象可检查属性的值是否有效。 WPF 具有以下两种类型的内置 ValidationRule 对象:
    ExceptionValidationRule 检查在更新绑定源属性的过程中引发的异常。
    DataErrorValidationRule 对象检查由实现 IDataErrorInfo 接口的对象所引发的错误。
    也可以通过从 ValidationRule 类派生和实现 Validate 方法来创建自己的验证规则。
    提供视觉反馈
    提供这种反馈的一种方式是将 Validation.ErrorTemplate 附加属性设置为自定义 ControlTemplate。
    验证过程
    目标的值传输到绑定源属性时通常会发生验证。 这种情况发生在 TwoWay 和 OneWayToSource 绑定上。
    调试机制
    可以在绑定相关对象上设置附加属性 PresentationTraceSources.TraceLevel 以接收有关特定绑定的状态的信息。

    展开全文
  • Data Binding作用:Data Binding在MVVM模式下就像个快递员,ViewModel中...所以说Binding是用来实现界面控件的属性与后台数据之间的绑定,通过这种形式将前台界面与后台数据联系在一起达到界面与数据解耦的目的。...

    前言:只要是涉及到MVVM开发,就不得不提Binding,现将Binding的一些知识点总结下,方便以后温故知新。

    一、简介

    Data Binding作用:Data Binding在MVVM模式下就像个快递员,ViewModel中处理好的数据就是绑定源,Binding这个快递员从这个绑定源中拿数据给绑定目标,一般是UI控件,绑定目标拿着这些数据更新自己的生活。有时候绑定目标也会退回一些东西给绑定源,也就是UI界面数据发生变化会回传到ViewModel中。所以说Binding是用来实现界面控件的属性后台数据之间的绑定,通过这种形式将前台界面与后台数据联系在一起达到界面与数据解耦的目的。

    由图可知,一个绑定由四部分组成:绑定目标目标属性绑定源源属性。 

    目标属性必须是依赖属性,这就意味着,不能绑定字段。UIElement对象的大部分属性是依赖属性并且这些大部分属性(除了只读)默认支持数据绑定的。 (只有 DependencyObject 类型可以定义依赖项属性,并且所有 UIElement 对象都派生自 DependencyObject.)

    1.1 Binding源

    根据数据驱动的精神,Binding的源就是数据的源头,数据的源头只要是一个对象,并且通过属性公开了自己的数据,既可作为Binding的源。包含数据的对象比比皆是,但必须为Binding的Source指定合适的对象Binding才能正常工作。

    Binding的源

    • 把普通CLR类型单个对象指定为Source。包括.NET Framework自带类型的对象和用户自定义类型的对象。
    • 把普通CLR集合类型对象指定为Source。包括数组、List<T>、ObservableCollection<T>等集合类型。
    • 把ADO.NET数据对象指定为Source。包括DataTable和DataView对象。
    • 把依赖对象指定为Source。
    • 把容器DataContext指定为Source。

    ContentControl类型,比如TextBox、Botton等,更多的是绑定单个属性,这个属性要么后台自定义,要么绑定UI控件的某个属性。

    列表类控件更多的是绑定集合,这个集合可能来自于数据库,也可能来自于xml、json等配置文件。

    微软针对XML绑定和对象绑定,提供了两个辅助类XmlDataProvider和ObjectDataProvider。

    这是Binding类的源属性,可以看出来,Source属性可以设置的数据源对象类型很多,基本上可以理解为两类,一类是UI控件,一种是自定义的后台数据对象。

    1.2 源属性

    数据源就是一个对象,一个对象本身可能会有很多数据,这些数据又通过属性暴露给外界。那么其中哪个元素是你想通过Bindidng送达UI元素的呢?换句话说,UI元素关心的是哪个属性值的变化呢?这个属性值称之为Binding的路径(Path)。但光有属性还不行,Binding是一种自动机制,当值变化后属性要有能力通知Binding,让Binding把变化传递给UI元素。怎样才能让一个属性具备这种通知Binding值变化改变的能力呢?方法使在属性的set语句中激发一个PropertyChanged事件。这个事件不需要我们自己声明,我们要做的事是让作为数据源的类实现System.ComponentModel

    名称空间中的INotifyPropertyChanged接口。当为Binding设置了数据源之后,Binding就会自动侦听来自这个接口PropertyChanged事件。

    二、Source类型

    前面也说了,这里的Source是泛指,并不明确指定这个绑定源就叫Source关键字,而是有很多对象都可以叫Source,如CLR对象等。但是,如果是在后台进行绑定,大部分都是使用的Source进行绑定的。当然Binding类中也有一个属性叫Source。但我们应用更多的还是下面这几种方式。

    2.1 ElementName(数据源明确)

    使用ElementName后数据源就明确了,这个绑定源就是ElementName属性值,比如下面这个名为sourceTBox的TextBox,同样绑定属性,也是这个TextBox的对应属性。TextBlock就会从这个TextBox源中拿对应的数据丰富自己。

     <TextBox x:Name="sourceTBox" />
     <TextBlock x:Name="tb" Text="{Binding ElementName=sourceTBox,Path=Text}" />

    为了代码简洁,默认的属性和默认的属性配制不需要在代码中重写设置,所有上面的代码可以优化成下面代码。

    <TextBox x:Name="sourceTBox" />
    <TextBlock x:Name="tb" Text="{Binding Text,ElementName=sourceTBox}" />

    绑定表达式中Path属性被省略,Path=Text简写成Text,为什么可以这样简写,是因为Binding类中有两个构造函数,也是为什么有些绑定中有"path"关键字,有些没有,没有的就是默认使用了这个带参构造函数。

    2.2 DataContext(数据源不明确)

    DataContext--如果没有使用Source和RelativeSource指定源,Wpf就从当前元素开始在元素树种向上查找。 

    DataContext是每一个继承FrameworkElement类的控件都有的属性,所以每一个UI控件都有此属性(包括布局控件),Binding只知道Path,不知道Source的话就会像UI树的根部找过,直到找到含有Path所指定的属性的对象没然后"借过来"用一下,如果最总没有找到那么就不会得到数据。

    DataContext属性是绑定的默认源,除非你具体指定了另外一个源,比如2.1中的ElementName属性。它由FrameworkElement类定义,大部分UI控件包括WPF窗口都继承于此类。简单的说,它允许你指定一个绑定基。

    <Grid>
        <TextBlock Text="{Binding S}" FontSize="30" Background="Beige"/>
    </Grid>
    public partial class MainWindow : Window
    {
        public string Name { get; set; } = "engcaipen";
        public string S { get; set; } = "hanyoushui";
    
        public MainWindow()
        {
            InitializeComponent();
                
            this.DataContext = this;
        }
    }

    这里没有指定数据源,同时简化了Path,由于窗口有一个DataContext,所以,程序默认就会将DataContext作为默认数据源,它可以传递给子控件,并沿着控件树自下往上找这个S。

    注意:

    • 自定义Name这个有问题,并不会被绑定,因为UI控件都有这个Name属性,容易产生歧义。
    • 需要手动设置下Window的DataContext属性,不然这个DataContext=null,同样没法绑定。
    • 同样的也可以将DataContext设置TextBlock的上级控件Grid的对应属性,反正需要设置下这个DataContext。

    使用DataContext属性就好像设置了所有绑定的基础,能够贯穿整个控件层次。这样就节省了手动为每一个绑定定义源。

    但是,这并不意味着你必须在一个窗口里面为所有控件使用同样的DataContext。由于每一个控件都有着自己的DataContext属性,你可以很容易的打破继承链,用新值来重写DataContext。这就允许你在窗口里使用一个全局DataContext,然后再像panel这样的地官方使用本地具体的DataContext。

    2.3 RelativeSource(不知道数据源名)

    Binding时,如果明确知道数据源的名字,可以使用ElementName和Source进行绑定,但是有些时候我们需要绑定的数据源可能没有明确的名字,此时我们就需要利用Binding的RelativeSource进行绑定。这种方式的意思是指当前元素和绑定源的位置关系。

    2.3.1 Self

    这种就是羊毛出在羊身上,自己既是绑定源元也是绑定目标。

    <TextBlock FontSize="18" FontWeight="Bold" Margin="10" 
    Background="Red" Width="80" Height="{Binding RelativeSource={RelativeSource Self},Path=Width}">MultiBinding Sample</TextBlock>

    这里将自身的Height属性绑定在自生的Width上面,其实就是Height=Width。

    2.3.2 AncestorType

        <Grid x:Name="g1" Background="Red" Margin="10">
            <DockPanel Name="d1" Background="Orange" Margin="10">
                <Grid x:Name="g2" Background="Yellow" Margin="10">
                    <DockPanel Name="d2" Background="LawnGreen" Margin="10">
                        <TextBox Name="textbox" FontSize="24" Margin="10"
                                 Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Grid},AncestorLevel=1},Path=Name}"/>
                    </DockPanel>
                </Grid>
            </DockPanel>
        </Grid>

    RelativeSource属性的数据类型为RelativeSource类,AncestorLevel指的是以Bingding目标控件为起点的层级偏移量,d2的偏移量是1,g2的偏移量是2,AncestorType指的是要找的目标对象的类型。值得注意的是AncestorLevel需要参考AncestorType使用,如上面设置了AncestorType={x:Type Grid},则Binding在寻找时会忽略非Grid的控件,此时g2的偏移量时1,g1的偏移量是2,DockPanel被忽略。

    2.3.3 TemplatedParent

    这个主要是在模板和数据模板中使用。此模式允许将给定的ControlTemplate 属性绑定到应用ControlTemplate 的控件属性。

        <Window.Resources>
            <ControlTemplate x:Key="template">
                <Canvas>
                    <Canvas.RenderTransform>
                        <RotateTransform Angle="20"/>
                        </Canvas.RenderTransform>
                    <Ellipse Height="100" Width="150"
                         Fill="{Binding
                    RelativeSource={RelativeSource TemplatedParent},
                    Path=Background}">
     
                      </Ellipse>
                    <ContentPresenter Margin="35"
                          Content="{Binding RelativeSource={RelativeSource 
                          TemplatedParent},Path=Content}"/>
                </Canvas>
            </ControlTemplate>
        </Window.Resources>
            <Canvas Name="Parent0">
            <Button   Margin="50"
                      Template="{StaticResource template}" Height="0"
                      Canvas.Left="0" Canvas.Top="0" Width="0">
                <TextBlock FontSize="22">Click me</TextBlock>
            </Button>
        </Canvas>

    如果我想应用给定控件的属性到它的控件模板,那么我可以使用TemplatedParent模式。也有类似的一个标记扩展的TemplateBinding是一种短手的第一个,但TemplateBinding是在编译时进行的对比TemplatedParent评估就是在第一次运行时。

    三、总结

    其实写到这里,笔者慢慢的才有了点感觉,而且也感觉文章整个布局有点乱,按照笔者之前的思考,主要想总结下这个绑定源和UI界面的关系,然后就把这种数据源分成前端(UI层)一份,后台(逻辑层)一份,慢慢的发现对于数据源理解有些错误,笔者之前对数据源的理解是Source、ElementName、DataContxt等,一直以为ElementName和DataContxt都属于控件的或者叫前端的数据源类型,根据官网及各位大佬的介绍,说这个数据源啊,只要是个对象,并公开了自己属性就可以,然后Binding正好有一个属性Source,以为这个Source是专门用来绑定后台(逻辑层)的数据源的,笔者就写了个Student类,然后在Xmal中通过Binding.Source将Student的实例绑定到TextBlock的Text中,发现不行。现在顿悟了:

    • 在c#代码中,可以访问XAML中声明的变量,但是XAML中不能访问c#中声明的变量,因此,要想在XAML中建立UI元素和逻辑对象的Binding,就需要把逻辑代码声明为XAML中的资源(Resource)。
    • 基于上一条规则,如果要在XAML中使用Binding的Source进行绑定逻辑层的数据源,就需要将逻辑层的数据源设置成XAML中的资源。这样们就不需要设置DataContext也能绑定这个自定义的Student源了。
    • Source关键字更多的是在后台进行绑定使用,而且是Binding类的属性,这个属性,在xaml中直接使用就不好使。
    //定义一个Student变量
    Student stu;
    public MainWindow()
    {
        InitializeComponent();
     
        //准备数据源       
        stu = new Student();
        //准备Binding
        Binding binding = new Binding();//创建Binding实例
        binding.Source = stu;//指定数据源
        binding.Path = new PropertyPath("Name");//指定访问路径 
     
        //使用Binding 连接数据源与Bingding目标
        BindingOperations.SetBinding(this.textBoxName,TextBox.TextProperty,binding);//使用binding实例将数据源与目标关联起来
        //参数为 目标;目标的某个属性
    }
    • CLR对象可以理解为我们需要自定义的或者重写的一些对象。如果是自定义的对象,就像Student一样,要使用Binding.Source进行绑定。

    在实际项目开发中,更多的数据源还是逻辑层的数据对象,这样可以显示从数据库或者文件中提取的数据。绑定源是非UI元素的对象时,需要放弃Binding.ElementName属性。绑定到逻辑层数据对象时,使用以下属性的其中一个:

    • Source--该属性是指向源对象的引用(数据的对象)
    • RelativeSource--这是引用,使用RelativeSource对象指向源对象,RelativeSource是一种特殊的工具,在对控件模板和数据模板进行二次创作时是很方便的。

    WPF数据绑定数据结构不能获取私有信息或公有字段(不是属性)。

    笔者应用最多的绑定源是DataContext,MVVM模式下通过设定View的DataContext属性,将ViewModel作为绑定源绑定到View中,然后在ViewModel中定义各种属性供View中的TextBolck、TextBox进行绑定,或者写几个类,将类的属性绑定给DataGrid使用,再或者定义一些集合,给ItemControl类控件使用。

    在写这篇之前,甚至是写这篇文章前半部分时候,笔者还以为自定义的这个Student是数据源,根本就没意识到其实是将ViewModel作为View的DataContext,所以对这个Binding.Source属性理解很混乱,包括现在也不是很清楚,只是需要先结束下,等有时间专门来总结下这个Binding.Source在XAML中的使用。

    四、参考文献

    4.1 Binding 类 (System.Windows.Data) | Microsoft Docs

    4.2 整理:WPF中Binding的几种写法 - mingruqi - 博客园

    4.3 C# Wpf Binding 使用详解_badxnui的博客-CSDN博客_wpfbinding

    4.4 WPF教程(三十五)使用DataContext_seanbei的博客-CSDN博客_datacontext

    4.5 WPF中的binding(九)- 使用Binding的RelativeSource_HymanLiuTS的博客-CSDN博客

    4.6 WPF绑定与RelativeSource结合使用_有技巧搬砖的博客-CSDN博客

    展开全文
  • WPF Binding绑定模式

    2022-03-22 00:00:59
    数据绑定的源可以是普通的 .NET 属性或 Dependency 属性,但目标属性必须是Dependency属性。 为了使绑定正常工作,属性的双方都必须提供通知中的更改,这将告诉绑定更新目标值。在普通的 .NET 属性中,可以通过使用...

    Binding是WPF 应用程序中的一种机制,它为应用程序提供了一种简单易用的方式来显示数据并与之交互。它允许数据在 UI 和业务模型之间流动。绑定完成后对业务模型中的数据所做的任何修改都会自动反映到 UI,反之亦然。

    绑定可以是单向的或双向的。数据绑定的源可以是普通的 .NET 属性或 Dependency 属性,但目标属性必须是Dependency属性。

    为了使绑定正常工作,属性的双方都必须提供通知中的更改,这将告诉绑定更新目标值。在普通的 .NET 属性中,可以通过使用INotifyPorpertyChanged接口来实现。而对于Dependency属性,它是由属性元数据的PropertyChanged回调完成的。

    数据绑定模式:

    模式描述
    OneWay源 → 目标
    TwoWay源 ←→ 目标
    OneWayToSource源 ← 目标
    OneTime源 → 目标 (仅一次)

    这可以通过 WPF 提供的不同类型的数据绑定表达式来实现。

    下面给出了数据绑定表达式的类型。

    • 数据上下文绑定
    • 相对源绑定
    • 集合绑定的当前项目

    数据上下文绑定

    DataContext 是一个 Dependency 属性,它是默认的绑定源。数据上下文沿逻辑树继承。因此,如果您设置一个数据上下文来控制逻辑树中的所有子元素,它也将引用相同的数据上下文,除非并且直到明确指定另一个源。

    • 创建一个类Book,如下:
    public class Book 
    {  
        public string Name 
        {  
            get;  
            set;  
        }  
        public string Author 
        {  
            get;  
            set;  
        }  
    }  
    
    • 添加一个 XAML 文件 DataContextBinding.xaml 并放置四个 Textblock,如下所示。
    <Grid VerticalAlignment="Center">  
        <Grid.RowDefinitions>  
            <RowDefinition Height="40" />  
            <RowDefinition Height="40" />  
        </Grid.RowDefinitions>  
        <Grid.ColumnDefinitions>  
            <ColumnDefinition Width="Auto" />  
            <ColumnDefinition Width="Auto" />  
        </Grid.ColumnDefinitions>  
        <TextBlock Text="Book Name:" FontWeight="Bold" />  
        <TextBlock Grid.Column="1" />  
        <TextBlock Text="Author:" FontWeight="Bold" Grid.Row="1" />  
        <TextBlock Grid.Row="1" Grid.Column="1" />  
    </Grid>  

    现在,让我们看看如何使用这个 DataContext 属性来显示数据。

    它有两种使用方式,如下所示。

    1. 使用 {Binding} 表达式

      用于直接绑定 DataContext。
      创建类 Book 的实例,初始化其属性并将类的 Name 属性分配给 Window 的 DataContext 属性。
    public partial class DataContextBinding: Window 
    {  
        public DataContextBinding() 
        {  
            InitializeComponent();  
            //Create the instance  
            Book book = new Book();  
            //initialize the properties  
            book.Name = "Computer Networking";  
            //Assign the Property as DataContext  
            this.DataContext = book.Name;  
        }  
    }  
    

    由于 Datacontext 是沿逻辑树和数据簿继承的,因此 name 绑定到 Control Window。Window 的所有子元素也将引用同一个对象(book.Name)。

    要显示数据,请将 DataContext 与 Textblock 绑定,如下所示。

    <TextBlock Text="Book Name:" FontWeight="Bold"/>  
    <TextBlock Text="{Binding}" Grid.Column="1" />   
    1. 输出

    1. 使用 {Binding Property} 表达式

      绑定 Datacontext 的属性。
      创建一个 Book 类的实例,初始化它的属性并将类(book)的实例分配给 Window 的 DataContext 属性。
     Book book = new Book();  
    //initialize the properties  
    book.Name = "Computer Networking";  
    book.Author = "James F. Kurose";  
    //Assign the instance as DataContext  
    this.DataContext = book;  
    

    现在,让我们看看输出。

    由于绑定表达式 {Binding} 用于绑定 Book 类型的 DataContext 对象,因此在其上调用 ToString() 方法并将数据显示为字符串。为了以正确的格式显示数据,我们必须绑定属性带有文本块的数据对象,如下图所示:

    <TextBlock Text="Book Name:" FontWeight="Bold"/>  
    <TextBlock Text="{Binding Name}" Grid.Column="1" />  
    <TextBlock Text="Author:" FontWeight="Bold" Grid.Row="1" />  
    <TextBlock Text="{Binding Author}" Grid.Row="1" Grid.Column="1"/>

    绑定表达式{Binding Name}用于绑定DataContext绑定的Name属性。

    输出

    RelativeSource Binding

    RelativeSource 是一个属性,它设置绑定源与绑定目标的相对关系。当您必须将元素的一个属性绑定到同一元素的另一个属性时,主要使用此扩展。

    有四种类型的RelativeSource,如下所示。

    1. Self
    2. FindAncestor
    3. TemplatedParent
    4. PreviousData

    让我们一一详细探讨。

    Self

    Self用于一个场景,当Binding源和绑定目标相同时。对象的一个​​属性与同一对象的另一个属性绑定。

    例如 - 让我们采用具有相同高度和宽度的椭圆。

    在 XAML 文件中添加下面给出的代码。宽度属性与高度属性相对绑定。

    <Grid>  
        <Ellipse Fill="Black" Height="100" Width="{Binding RelativeSource={RelativeSource Self},Path=Height}">  
        </Ellipse>  
    </Grid>   

    输出

    如果 Ellipse 的高度发生变化,宽度也会相对变化。

    FindAncestor

    顾名思义,这在绑定源是绑定目标的祖先(父母)之一时使用。使用 FindAncestor 扩展,您可以找到任何级别的祖先。

    让我们举个例子来更清楚地理解它。

    创建 XAML,它表示下面给出的元素的逻辑树。

    <Grid Name="Parent_3">  
        <StackPanel Name="Parent_2">  
            <Border Name="Parent_1">  
                <StackPanel x:Name="Parent_0" Orientation="Vertical">  
                    <Button></Button>  
                </StackPanel>  
            </Border>  
        </StackPanel>  
    </Grid>  

    现在,让我们使用 FindAncestor 扩展将祖先的名称属性绑定到子元素按钮的内容属性。

    <Grid Name="Parent_3">
        <StackPanel Name="Parent_2" HorizontalAlignment="Center" VerticalAlignment="Center" Width="100">  
            <Border Name="Parent_1">  
                <StackPanel x:Name="Parent_0" Orientation="Vertical">  
                    <Button Height="50" Content="{Binding RelativeSource={RelativeSource FindAncestor,  
    AncestorType={x:Type StackPanel},  
    AncestorLevel=2},Path=Name}"></Button>  
                </StackPanel>  
            </Border>  
        </StackPanel>  
    </Grid>

    输出

    AncestorType “StackPanel” 结合 AcestorLevel as “2” 将 button 的 content 属性与 StackPanel (Parent_2) 的 Name 属性绑定。

    TemplatedParent

    TemplatedParent 是一个属性,它使您能够创建具有少量未知值的控件模板。这些值取决于应用 ControlTemplate 的控件的属性。

    让我们举个例子来更详细地理解它

    • 为按钮创建一个ControlTemplate,如下所示。
    <Window.Resources>
        <ControlTemplate x:Key="template">  
            <Canvas>  
                <Ellipse Height="110" Width="155"  
                 Fill="Black"/>  
                <Ellipse Height="100" Width="150"  
                 Fill="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Background}">  
                </Ellipse>  
                <ContentPresenter Margin="35"  
                 Content="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Content}"/>  
           </Canvas>
        </ControlTemplate>
    </Window.Resources>

    在上面给出的代码中,Ellipse 的示例 Fill 属性和 ContentPresenter 的 Content 属性取决于将应用此模板的控件的属性值。

    • 添加一个按钮并将模板应用到它。
    <Button Margin="50" Background="Beige" Template="{StaticResource template}" Height="0" Content="Click me" FontSize="22">  
    </Button>   

    在应用模板时,按钮的Background(Beige)与Ellipse的Fill属性相对绑定,Content(点我)与ContentPresenter的Content属性相对绑定。评估相关值并给出下面给出的输出。
    输出:

    PreviousData

    这是RelativeSource 最少使用的模式。这在分析数据时出现,我们需要表示相对于先前数据的值变化。

    让我们举个例子来更详细地理解它。

    • 创建一个Data类并实现INotifyPropertyChanged接口,如下图
    public class Data: INotifyPropertyChanged 
    {  
        public int DataValue 
        {  
            get;  
            set;  
        }  
        public event PropertyChangedEventHandler PropertyChanged;  
        protected void OnPropertyChanged(string PropertyName) 
        {  
            if (null != PropertyChanged) 
            {  
                PropertyChanged(this,  
                    new PropertyChangedEventArgs(PropertyName));  
            }  
        }  
    }   
    
    • 创建一个列表以键入 Data 并将其分配为 DataContext。
    public RelativeSourcePreviousData() 
    {  
        InitializeComponent();  
        List < Data > data = new List < Data > ();  
        data.Add(new Data() 
        {  
            DataValue = 60  
        });  
        data.Add(new Data() 
        {  
            DataValue = 100  
        });  
        data.Add(new Data() 
        {  
            DataValue = 120  
        });  
        this.DataContext = data;  
    }   
    
    • 在 XAML 文件中添加 ItemsControl。
    <ItemsControl ItemsSource="{Binding}"></ItemsControl>  
    • 为其创建 ItemsPanel 模板,如下所示。
    <ItemsControl ItemsSource="{Binding}">  
        <ItemsControl.ItemsPanel>  
            <ItemsPanelTemplate>  
                <StackPanel Orientation="Vertical" />  
            </ItemsPanelTemplate>  
        </ItemsControl.ItemsPanel>  
    </ItemsControl>  
    • 现在,为了正确表示数据,创建 DataTemplate,如下所示。
    <ItemsControl.ItemTemplate>
        <DataTemplate>  
            <StackPanel Orientation="Horizontal">  
                <Grid Margin="30,20,0,0">  
                    <Rectangle Width="80" Height="{Binding DataValue}" Fill="Blue" />  
                    <TextBlock Foreground="White" Margin="35,0,0,0" Text="{Binding DataValue}"></TextBlock>  
                </Grid>  
                <TextBlock Margin="30,20,0,0" Text="Previous Data:"></TextBlock>  
                <TextBlock VerticalAlignment="Center" Margin="5,20,0,0" Text="{Binding  
                 RelativeSource={RelativeSource PreviousData}, Path=DataValue}" />  
            </StackPanel>  
        </DataTemplate>  
    </ItemsControl.ItemTemplate>

    输出

    蓝色框的高度是列表中项目的值,之前的数据显示在框的右侧。项目的第一个值为“60”。因此,先前的数据显示第一项没有价值。

    展开全文
  • 前言:WPF数据绑定对于WPF应用程序来说尤为重要,本文将讲述使用MVVM模式进行数据绑定的四步走用法: 具体实例代码如下: 以下代码仅供参考,如有问题请在评论区留言,谢谢 复制代码 1 第一步:声明一个类用来实现...
  • WPF--依赖属性

    千次阅读 2022-03-01 15:51:03
    WPF--依赖属性 大家都知道WPF带来了很多新的特性,其中一个就是引入了一种新的属性...依赖属性根据多个提供对象来决定它的值 (可以是动画、父类元素、绑定、样式和模板等),同时这个值也能及时响应变化。 依赖属性
  • WPF 命令绑定的各种方式

    千次阅读 2020-01-21 09:24:08
    WPF 命令绑定的各种方式 引言 在WPF开发过程中,不得不学习的就是MVVM模式。但是在MVVM中又绕不开命令(Command)的使用。下面通过几种方式介绍我了解的WPF命令绑定方式。 如何使用 控件继承ICommand接口,直接...
  • WPF MVVM--数据绑定

    2022-04-28 09:19:07
    WPF MVVM--数据绑定 一、数据绑定要达到的效果 数据绑定要达到什么效果呢,就是在界面中绑定了数据源之后,数据在界面上的修改能反映到绑定源,同时绑定源的修改也能反映到界面上。从界面反映到绑定的数据源是很...
  • 有很多文章讨论绑定的概念,并讲解如何使用StaticResources和DynamicResources绑定属性。这些概念使用WPF提供的数据绑定表达式。在本文中,让我们研究WPF提供的不同类型的数据绑定表达式。 介绍购优惠 ...
  • C#WPF XAML属性

    2021-09-08 21:06:42
    C#WPF XAML属性 一、属性语法 1.属性是对XAML元素特征进行描述的方法;属性不允许在XAML中重复设置多次;允许 在托管代码中改变元素的属性值 。 (1)、属性设置的几种方式: 使用特性语法(属性语法)、使用属性...
  • WPF 绑定数据的验证

    2021-04-26 19:58:43
    验证类型 说明 Exception 验证 ... Binding 类具有一个用于提供 ValidationRule 派生类实例的集合的属性。这些 ValidationRules 需要覆盖某个 Validate 方法,该方法由 Binding 在每次绑定控件中的数据
  • 在我们平时的开发中会经常用到Image控件,通过设置Image控件的Source属性,我们可以加载图片,设置Image的source属性时可以使用相对路径也可以使用绝对路径,一般情况下建议使用绝对路径,类似于下面的形式Source="/...
  • 这次讲解的命令绑定,主要解决的问题是,为实现MVVM模式进行铺垫,实现前后台逻辑的解耦。我们知道如果Button直接实现Click事件,那么实现的逻辑必然在Window后台代码中,为了实现MVVM,我要将业务逻辑放在ViewMode...
  • MVVM模式解析和在WPF中的实现(二)数据绑定系列目录:0x00 数据绑定要达到的效果数据绑定要达到什么效果呢,就是在界面中绑定了数据源之后,数据在界面上的修改能反映到绑定源,同时绑定源的修改也能反映到界面上。...
  • 一.简介  为了后面行文顺利,在进入正文之前,我们首先对本文所涉及到的绑定...绑定源用来标示源属性所存在的类型实例,路径用来标示需要绑定到的处于绑定源之上的源属性绑定目标标示将接受相应更改的属性所在的...
  • 三、数据外衣DataTemplate ~~~~ 同样一条数据,比如具有Id、Name、PhoneNumber、Address等属性的Student实例,放在GridView里有时可能就是简单的文本、每个单元格只显示一个属性;放在ListBox里有时为了避免单调...
  • wpf中的那些模板之深度解析
  • 初步了解WPF依赖属性

    2021-01-08 01:50:18
    依赖属性重要性在于,在WPF核心特性,如动画、数据绑定以及样式中都需要使用到依赖属性WPF中的依赖属性主要有以下三个优点: 依赖属性加入了属性变化通知、限制、验证等功能。这样可以使我们更方便地实现应用,...
  • WPF 中 数据绑定 ItemSource和 DataContext的不同点:(1)DataContext 一般是一个非集合性质的对象,而ItemSource 更期望数据源是 集合对象。(2)DataContext 是 FrameworkElement 类中定义的一个依赖属性...
  • WPF ComboBox 使用 ResourceBinding 动态绑定资源键并支持语言切换独立观察员 2021 年 8 月 23 日我们平常在WPF中进行资源绑定操作,一般就是用...
  • 一、创建一个简单的Binding的简单程序 1.1.数据绑定概述 数据绑定为应用程序提供了一种简单、一致的数据表示和交互方法。...WPF中的数据绑定功能与传统模型相比具有一些优势,包括本质上支持数据绑定的各种属性、灵活
  • WPF--属性系统

    2022-02-24 16:23:13
    WPF--属性系统 Windows Presentation Foundation(WPF)提供了一组服务,这些服务可用于扩展公共语言运行库(CLR)属性的功能。这些服务通常统称为WPF属性系统。由 WPF 属性系统支持的属性称为依赖项属性。本概述介绍...
  • MSDN里如是说:通常,如果有多个 DataTemplate 可用于同一类型的对象,并且您希望根据每个数据对象的属性提供自己的逻辑来选择要应用的 DataTemplate,则应创建 DataTemplateSelector。请注意,如果具有不同类型的...
  • WPF元素绑定

    2018-08-15 00:25:00
    数据绑定简介:数据绑定是一种关系,该关系告诉WPF从源对象提取一些信息,并用这些信息设置目标对象的属性。目标属性是依赖项属性。源对象可以是任何内容,从另一个WPF元素乃至ADO.NET数据对象(如DataTable)或自行...
  • WPF开发教程.doc

    2019-07-02 23:18:19
    3. WPF数据绑定之数据模板 166 4. WPF数据绑定绑定声明 181 5. 实例一:绑定到ADO.NET数据源 184 6. 实例二:绑定到LINQ查询的结果 186 WPF图形和多媒体开发 187 1. WPF 图形动画和媒体概述 187 2. WPF的图形呈现 ...
  • WPF Image控件的绑定 在我们平时的开发中会经常用到Image控件,通过设置Image控件的Source属性,我们可以加载图片,设置Image的source属性时可以使用相对路径也可以使用绝对路径,一般情况下建议使用绝对...
  • 控件模板可对控件的内容和样式均做出改变。 项目源码 防止两个按钮,第一个为普通按钮,第二个应用了控件模板: <Window.Resources> <ControlTemplate x:Key="ButtonTemplate" TargetType="{x:Type Button...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,623
精华内容 1,049
热门标签
关键字:

wpf模板绑定实例属性