吴佳鑫的个人专栏

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

导航

silverlight DataContext

1、DataContext 是在 FrameworkElement 里面的一个属性。

FrameworkElement 的关系可以看上一个日记。

2、简单来说,FrameworkElement 是所有可视化界面元素的基类,而DataContext 是它里面的一个属性。

我们的 绑定是基于使用这个  DataContext 去做绑定的,对于所有的界面都可以这么做。

3、DataContext 的特征,它会通知它的视觉树(VisualTree)下面的子节点。

 

 

来一个经典DEMO:

using System.Windows.Data;
using System.Windows.Media;
using System.Windows;
using System;

namespace Class4Samples
{
    public class GetVisualParentConverter : IValueConverter
    {
        #region IValueConverter Members
        public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            DependencyObject parent = value as DependencyObject;
            while (true)
            {
                parent = VisualTreeHelper.GetParent(parent as DependencyObject);
                if (parent == null)
                    break;

                if (parameter as string == parent.GetType().ToString())
                {
                    return parent;
                }
            }
            return null;
        }

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

 

 

前台XAML: 这里有很多绑定技巧,需要理解清楚!

<UserControl
    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:local="clr-namespace:Class4Samples" 
    xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
    x:Class="Class4Samples.DataContext"
    mc:Ignorable="d"
    x:Name="userControl" 
    d:DesignWidth="640" d:DesignHeight="480">

    <UserControl.Resources>
        <local:GetVisualParentConverter x:Key="GetVisualParentConverterDataSource" d:IsDataSource="True"/>
        <Style x:Key="ContentControlStyle" TargetType="ContentControl">
            <Setter Property="Foreground" Value="#FF000000"/>
            <Setter Property="HorizontalContentAlignment" Value="Left"/>
            <Setter Property="VerticalContentAlignment" Value="Top"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ContentControl">
                        <Border BorderBrush="#FFA9FFBF" BorderThickness="5" CornerRadius="10">
                            <ComboBox ItemsSource="{Binding}"/>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        <DataTemplate x:Key="DataTemplate">
            <Border BorderBrush="#FF1BB8FF" BorderThickness="1" CornerRadius="10">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition/>
                        <ColumnDefinition/>
                    </Grid.ColumnDefinitions>
                    <TextBlock Foreground="#FF002EFF" Text="{Binding}" TextWrapping="Wrap" Height="20"/>
                    <TextBlock Text="Parent: " TextWrapping="Wrap" Grid.Row="1"/>
                    <TextBlock Grid.Column="1" Text="{Binding ., RelativeSource={RelativeSource TemplatedParent}}" TextWrapping="Wrap" d:LayoutOverrides="Width, Height" Grid.Row="1"/>
                    <TextBlock Text="Parent.Parent: " TextWrapping="Wrap" Grid.Row="2"/>
                    <TextBlock Grid.Column="1" Text="{Binding Parent, RelativeSource={RelativeSource TemplatedParent}}" TextWrapping="Wrap" d:LayoutOverrides="Width, Height" Grid.Row="2"/>
                    <TextBlock Text="Parent.Parent.Parent: " TextWrapping="Wrap" Grid.Row="3"/>
                    <TextBlock Grid.Column="1" Grid.Row="3" Text="{Binding Parent.Parent, RelativeSource={RelativeSource TemplatedParent}}" TextWrapping="Wrap" d:LayoutOverrides="Width, Height"/>
                    <TextBlock Text="GetVisualParentConverter to Get ListBox: " TextWrapping="Wrap" Grid.Row="4"/>
                    <TextBlock Grid.Column="1" Grid.Row="4" 
                    Text="{Binding Converter={StaticResource GetVisualParentConverterDataSource}, 
                    ConverterParameter=System.Windows.Controls.ListBox, Mode=OneWay}" 
                    DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}" TextWrapping="Wrap"/>
                </Grid>
            </Border>
        </DataTemplate>
    </UserControl.Resources>

    <Grid x:Name="LayoutRoot">
        <Grid VerticalAlignment="Top" DataContext="{Binding Items, ElementName=userControl, Mode=OneWay}" HorizontalAlignment="Center" Width="400">
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <TextBlock VerticalAlignment="Top" Text="{Binding}" TextWrapping="Wrap"/>
            <ListBox VerticalAlignment="Top" Grid.Row="1" ItemsSource="{Binding}"/>
            <ComboBox VerticalAlignment="Top" Height="20" Grid.Column="1">
                <ListBox ItemsSource="{Binding}"/>
                <data:DataGrid ItemsSource="{Binding}"/>
            </ComboBox>
            <ContentControl Grid.Row="1" Style="{StaticResource ContentControlStyle}" Grid.Column="1"/>
        </Grid>
        <ListBox ItemTemplate="{StaticResource DataTemplate}" 
        ItemsSource="{Binding Items, ElementName=userControl, Mode=OneWay}" x:Name="list" Margin="120,136,120,120"/>
    </Grid>
</UserControl>

 

后台CS代码:

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;

namespace Class4Samples
{
    public partial class DataContext : UserControl
    {
        public DataContext()
        {
            // Required to initialize variables
            InitializeComponent();
            this.PrepareDatas();
        }

        private void PrepareDatas()
        {
            this.Items = new ObservableCollection<string>();
            this.Items.Add("Lewis Wu");
            this.Items.Add("Jerry Jiang");
            this.Items.Add("Martin Du");
        }

        public ObservableCollection<string> Items
        {
            get { return (ObservableCollection<string>)GetValue(ItemsProperty); }
            set { SetValue(ItemsProperty, value); }
        }

        public static readonly DependencyProperty ItemsProperty =
            DependencyProperty.Register("Items", typeof(ObservableCollection<string>), typeof(DataContext), new PropertyMetadata(null));
    }
}

 

posted on 2012-08-21 01:04  _eagle  阅读(1763)  评论(0编辑  收藏  举报