Свойства зависимостей и контекст данных в Silverlight 3 - PullRequest
0 голосов
/ 15 июня 2009

Я работаю с бета-версией Silverlight 3, и у меня возникла проблема. У меня есть страница, на которой есть пользовательский элемент управления. Пользовательский элемент управления имеет свойство зависимости от него. Если пользовательский элемент управления не определяет контекст данных (следовательно, использует контекст данных родителя), все работает хорошо. Но если пользовательский элемент управления имеет свой собственный контекст данных, метод OnPropertyChanged свойства зависимостей никогда не вызывается.

Вот пример:

Моя главная страница:

    <UserControl x:Class="TestDepProp.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
             xmlns:app="clr-namespace:TestDepProp"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Width="400" Height="100">
    <Grid x:Name="LayoutRoot" Background="White">
        <Border BorderBrush="Blue" BorderThickness="3" CornerRadius="3">
            <StackPanel Orientation="Horizontal">
                <StackPanel Orientation="Vertical">
                    <TextBlock Text="Enter text here:" />
                    <TextBox x:Name="entryBlock" Text="{Binding Data, Mode=TwoWay}"/>
                    <Button Content="Go!" Click="Button_Click" />
                    <TextBlock Text="{Binding Data}" />
                </StackPanel>
                <Border BorderBrush="Blue" BorderThickness="3" CornerRadius="3" Margin="5">
                    <app:TestControl PropOnControl="{Binding Data}" />
                </Border>
            </StackPanel>
        </Border>
    </Grid>
</UserControl>

Код главной страницы:

    using System.Windows;
using System.Windows.Controls;

namespace TestDepProp
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
            MainPageData data = new MainPageData();

            this.DataContext = data;
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            int i = 1;
            i++;
        }
    }
}

Контекст данных главной страницы:

    using System.ComponentModel;

namespace TestDepProp
{
    public class MainPageData:INotifyPropertyChanged
    {

        string _data;
        public string Data
        {
            get
            {
                return _data;
            }
            set
            {
                _data = value;
                if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Data"));
            }
        }

        public MainPageData()
        {
            Data = "Initial Value";
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion
    }
}

Контроль XAML:

    <UserControl x:Class="TestDepProp.TestControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
             xmlns:app="clr-namespace:TestDepProp"
    >
    <Grid x:Name="LayoutRoot" Background="White">
        <StackPanel Orientation="Vertical" Margin="10" >
            <TextBlock Text="This should change:" />
            <TextBlock x:Name="ControlValue" Text="Not Set" />
        </StackPanel>
    </Grid>
</UserControl>

Контрольный код:

    using System.Windows;
using System.Windows.Controls;

namespace TestDepProp
{
    public partial class TestControl : UserControl
    {
        public TestControl()
        {
            InitializeComponent();
            // Comment out next line for DP to work
            DataContext = new MyDataContext();
        }


        #region PropOnControl Dependency Property

        public string PropOnControl
        {
            get { return (string)GetValue(PropOnControlProperty); }
            set { SetValue(PropOnControlProperty, value); }
        }

        public static readonly DependencyProperty PropOnControlProperty =
                    DependencyProperty.Register("PropOnControl", typeof(string), typeof(TestControl), new PropertyMetadata(OnPropOnControlPropertyChanged));

        private static void OnPropOnControlPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TestControl _TestControl = d as TestControl;
            if (_TestControl != null)
            {
                _TestControl.ControlValue.Text = e.NewValue.ToString(); 
            }
        }
        #endregion PropOnControl Dependency Property

    }
}

Контекст данных элемента управления:

    using System.ComponentModel;

namespace TestDepProp
{
    public class MyDataContext : INotifyPropertyChanged
    {

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion
    }
}

Чтобы попробовать, введите что-нибудь в текстовое поле и нажмите кнопку «Перейти». Закомментируйте контекст данных в коде элементов управления, чтобы убедиться, что он начинает работать.

Надеюсь, у кого-то есть представление о том, что происходит.

1 Ответ

0 голосов
/ 27 июня 2009

Текст данных пользовательского элемента управления не имеет свойства Data.

Поскольку у него нет свойства данных, привязка данных возвращает нуль, который уже является значением по умолчанию, поэтому изменение свойства никогда не срабатывает.

...