吴佳鑫的个人专栏

当日事当日毕,没有任何借口

导航

silverlight Binding 详解

 

这个日记介绍:
•Binding with Tools  (在blend中绑定)
•Binding with Handwriting (在代码中手工绑定)
 
一、数据源绑定
一般我们在做demo时会提供一些示例数据,在blend中,创建示例数据源是非常简单的。下面介绍两种数据源的创建方法。
在blend中,点击data面板,会见到两个类型饼图的小图标。
1、Single Data (右边的按键)
2、List Data (左边的按键)
 
 
下图为创建 Single Data 数据源:

创建这种的示例数据源,可以提供给单个对象使用。比例下图的一个Point对象(需要一个X轴和Y轴数据)

 

下图为创建List Data 数据源:(可以创建class,也可以从XML文件中导入)

 

创建完数据源,我们需要绑定到界面上。可以在blend中,某个属性后的 小矩形点击后,选择“数据绑定...”,会出来一个面板,上面有三个tab。

第一个tab: 绑定我们刚才那样子用blend 创建出来的,或者导入XML进来的数据源。

第二个tab: 绑定本地其它界面元素

第三个tab: 绑定上下文

 

 

手工绑定: 我们也可以用手工编写XAML来绑定。  

在blend中,点击某个属性后,选择“自定义表达式”的选项,就可以手工编写XAML绑定语句了。

下面介绍几点类型:

1、Bind Element Property

2、Bind DataContext

3、Bind Data Source

 

一、Bind Element Property

像刚才那样我们要绑定界面上的一个元素的时候,我们要指定一个 ElementName.来一个图

ElementName是指界面上的哪一个元素。

Path 对应的是这个元素的哪一个属性。

 

二、Bind DataContext (只能手工编写,不能用工具生成)

 

 如果是在一个已知上下文的范围内去做绑定的话,那我们可以直接这么写:  {Binding .}

这么写,表示我们已经绑定到上下文的根节点上了。

 

三、Bind Data Source

绑定数据源,有两种情况:

1)如下图:

这一种情况可以对我们之前用blend工具生成的数据源来做绑定

2)如下图:(只能手工编写,不能用工具生成)

这个实际上是对父亲节点来做的绑定。来一个例子:

我们把button做成这样:(编辑了外观了的:由一个文本框和一个button组成一个button)

贴上代码:

<Button Height="41" VerticalAlignment="Bottom" Content="Double Click to Submit " Style="{StaticResource ButtonStyle}" Click="OnSubmitInput"/>

模板是这样的:

View Code
        <Style x:Key="ButtonStyle" TargetType="Button">
            <Setter Property="Background" Value="#FF1F3B53"/>
            <Setter Property="Foreground" Value="#FF000000"/>
            <Setter Property="Padding" Value="3"/>
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="BorderBrush">
                <Setter.Value>
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="#FFA3AEB9" Offset="0"/>
                        <GradientStop Color="#FF8399A9" Offset="0.375"/>
                        <GradientStop Color="#FF718597" Offset="0.375"/>
                        <GradientStop Color="#FF617584" Offset="1"/>
                    </LinearGradientBrush>
                </Setter.Value>
            </Setter>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Button">
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition/>
                                <ColumnDefinition Width="Auto"/>
                            </Grid.ColumnDefinitions>
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="CommonStates">
                                    <VisualState x:Name="Normal"/>
                                    <VisualState x:Name="MouseOver">
                                        <Storyboard>
                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="BackgroundAnimation" Storyboard.TargetProperty="Opacity">
                                                <SplineDoubleKeyFrame KeyTime="0" Value="1"/>
                                            </DoubleAnimationUsingKeyFrames>
                                            <ColorAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)">
                                                <SplineColorKeyFrame KeyTime="0" Value="#F2FFFFFF"/>
                                            </ColorAnimationUsingKeyFrames>
                                            <ColorAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[2].(GradientStop.Color)">
                                                <SplineColorKeyFrame KeyTime="0" Value="#CCFFFFFF"/>
                                            </ColorAnimationUsingKeyFrames>
                                            <ColorAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[3].(GradientStop.Color)">
                                                <SplineColorKeyFrame KeyTime="0" Value="#7FFFFFFF"/>
                                            </ColorAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Pressed">
                                        <Storyboard>
                                            <ColorAnimationUsingKeyFrames Storyboard.TargetName="Background" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)">
                                                <SplineColorKeyFrame KeyTime="0" Value="#FF6DBDD1"/>
                                            </ColorAnimationUsingKeyFrames>
                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="BackgroundAnimation" Storyboard.TargetProperty="Opacity">
                                                <SplineDoubleKeyFrame KeyTime="0" Value="1"/>
                                            </DoubleAnimationUsingKeyFrames>
                                            <ColorAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[0].(GradientStop.Color)">
                                                <SplineColorKeyFrame KeyTime="0" Value="#D8FFFFFF"/>
                                            </ColorAnimationUsingKeyFrames>
                                            <ColorAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)">
                                                <SplineColorKeyFrame KeyTime="0" Value="#C6FFFFFF"/>
                                            </ColorAnimationUsingKeyFrames>
                                            <ColorAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[2].(GradientStop.Color)">
                                                <SplineColorKeyFrame KeyTime="0" Value="#8CFFFFFF"/>
                                            </ColorAnimationUsingKeyFrames>
                                            <ColorAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[3].(GradientStop.Color)">
                                                <SplineColorKeyFrame KeyTime="0" Value="#3FFFFFFF"/>
                                            </ColorAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Disabled">
                                        <Storyboard>
                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="DisabledVisualElement" Storyboard.TargetProperty="Opacity">
                                                <SplineDoubleKeyFrame KeyTime="0" Value=".55"/>
                                            </DoubleAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                                <VisualStateGroup x:Name="FocusStates">
                                    <VisualState x:Name="Focused">
                                        <Storyboard>
                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="FocusVisualElement" Storyboard.TargetProperty="Opacity">
                                                <SplineDoubleKeyFrame KeyTime="0" Value="1"/>
                                            </DoubleAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Unfocused"/>
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                            <TextBox TextWrapping="Wrap" d:LayoutOverrides="Height" Text="{Binding Tag, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"/>
                            <Grid Grid.Column="1">
                                <Border x:Name="Background" Background="White" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="3">
                                    <Grid Margin="1" Background="{TemplateBinding Background}">
                                        <Border x:Name="BackgroundAnimation" Opacity="0" Background="#FF448DCA"/>
                                        <Rectangle x:Name="BackgroundGradient">
                                            <Rectangle.Fill>
                                                <LinearGradientBrush EndPoint=".7,1" StartPoint=".7,0">
                                                    <GradientStop Color="#FFFFFFFF" Offset="0"/>
                                                    <GradientStop Color="#F9FFFFFF" Offset="0.375"/>
                                                    <GradientStop Color="#E5FFFFFF" Offset="0.625"/>
                                                    <GradientStop Color="#C6FFFFFF" Offset="1"/>
                                                </LinearGradientBrush>
                                            </Rectangle.Fill>
                                        </Rectangle>
                                    </Grid>
                                </Border>
                                <ContentPresenter x:Name="contentPresenter" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"/>
                                <Rectangle x:Name="DisabledVisualElement" Fill="#FFFFFFFF" RadiusX="3" RadiusY="3" IsHitTestVisible="false" Opacity="0"/>
                                <Rectangle x:Name="FocusVisualElement" Stroke="#FF6DBDD1" StrokeThickness="1" RadiusX="2" RadiusY="2" Margin="1" IsHitTestVisible="false" Opacity="0"/>
                            </Grid>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

可以看到里面有一句这样的:

<TextBox TextWrapping="Wrap" d:LayoutOverrides="Height" Text="{Binding Tag, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"/>

 

我们要的功能是:在点击那个button的时候,在事件里面可以取到在 TextBox 中输入的内容是什么。

这样的一种需求,我们实际是就是做了这样的绑定

Text="{Binding Tag, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"

就是用TextBox的 Text属性,绑定了它的父亲节点,也就是一整个的button 的 Tag 属性,而且是双向绑定。

这样的话,我们在TextBox中做输入的话,对应的整个button 的 Tag属性就会跟着变。

然后在click事件中,我们就可以通过button的 Tag去取得我们刚才输入的值。

  private void OnSubmitInput(object sender, System.Windows.RoutedEventArgs e)
  {
   this.result.Text = (sender as FrameworkElement).Tag as string;
  }

 为什么我们要用这种绑定呢,而不用前面提到的TemplatedBinding呢,这是因为我们现在这种方式是反向绑定,我们要做的是在button模板中的textbox 的值改变的时候,它的父亲节点的属性改变,而不是那个父亲节点的属性改变后让这个textbox跟着改。

而TemplatedBinding是一个单向的,也就是母改子改。所以它是做不到这个需求的。

 

 

四、Binding有多种写法:如下图

 

 

最后的tip: 我们在绑定的时候经常会用到转换器,一般都在要 资源里 写XAML来引用转换器。

我们可以不用写XAML代码,而在blend里面操作。

 步骤:1、先编写转换器。

         2、 在要用到转换器的页面中,打开blend的 data 面板,像最开始说到的那样,创建一个single data ,然后找到转换器。再点OK,blend就会自动在XAML写了引用某个转换器的代码 。 如:

 <UserControl.Resources>
  <local:NumberToArrowStyleConverter x:Key="NumberToArrowStyleConverter"/>
 </UserControl.Resources>

         3、接下来你怎么绑定就怎么搞了。

posted on 2012-08-16 01:46  _eagle  阅读(3919)  评论(0编辑  收藏  举报