Dependency Properties and Data Context in Silverlight 3

那年仲夏 提交于 2019-12-23 04:23:19

问题


I am working with Silverlight 3 beta, and am having an issue. I have a page that has a user control that I worte on it. The user control has a dependency property on it. If the user control does not define a data context (hence using the parent's data context), all works well. But if the user control has its own data context, the dependency property's OnPropertyChanged method never gets called.

Here is a sample:

My Main Page:

    <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>

Main Page code:

    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++;
        }
    }
}

Main Page's data context:

    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
    }
}

Control 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>

Contol code:

    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

    }
}

Control's data context:

    using System.ComponentModel;

namespace TestDepProp
{
    public class MyDataContext : INotifyPropertyChanged
    {

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion
    }
}

To try it out, type something in the text box, and hit the Go button. Comment out the data context in the controls code to see that it starts to work.

Hope someone has an idea as to what is going on.


回答1:


The user control's datacontext does not have a Data property.

Because it doesn't have a data property the databinding returns null which is already the default value so the property change never fires.



来源:https://stackoverflow.com/questions/995072/dependency-properties-and-data-context-in-silverlight-3

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!