none
Не передается контекст в UserControl в Silverlight RRS feed

  • Вопрос

  • Есть первый UserControl.

    Есть второй UserControl, вставленный в первый вот так:

    <uc:InternalControl
        DataContext="{Binding Path=MyContext}" />

    Поле MyContext из ViewModel первого контрола доступно (в общим с ним все в порядке). Однако контекст во второй контрол не передается (т.е. я проверяю свойство DataContext dj втором контроле и оно равно null).

    Что я делаю неправильно?


    26 июня 2012 г. 18:10

Ответы

  • Вот рабочий пример на скорую руку:

     public class TestViewModel1: INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
    
            private string _message;
            public string Message 
            {
                get
                {
                    return _message;
                }
                set
                {
                    if (_message!= value)
                    {
                        _message = value;
                        RaisePropertyChanged("Message");    
                    }
                } 
            }
    
            protected void RaisePropertyChanged(string propertyName)
            {
                if (PropertyChanged!= null)
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
    
            private TestViewModel2 _innerContext;
            public TestViewModel2 InnerContext
            {
                get { return _innerContext; }
                set
                {
                  if (_innerContext!= value)
                  {
                      _innerContext = value;
                      RaisePropertyChanged("InnerContext");    
                  }
                } 
            }
        }
    
    
        public class TestViewModel2 : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
    
            private string _message;
            public string Message
            {
                get
                {
                    return _message;
                }
                set
                {
                    if (_message != value)
                    {
                        _message = value;
                        RaisePropertyChanged("Message");
                    }
                }
            }
    
            protected void RaisePropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

    SilverlightControl1.xaml

    <UserControl x:Class="SilverlightApplication7.SilverlightControl1"
        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"
        mc:Ignorable="d"
        d:DesignHeight="300" d:DesignWidth="400">
        
        <Grid x:Name="LayoutRoot" Background="White">
            <TextBlock Text="{Binding Message}"/>
        </Grid>
    </UserControl>
    <UserControl x:Class="SilverlightApplication7.MainPage"
        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:SilverlightApplication7="clr-namespace:SilverlightApplication7" mc:Ignorable="d"
        d:DesignHeight="300" d:DesignWidth="400">
    
        <Grid x:Name="LayoutRoot" Background="White">
            <SilverlightApplication7:SilverlightControl1 DataContext="{Binding InnerContext}"/>
        </Grid>
    </UserControl>
    

    App.cs

     private void Application_Startup(object sender, StartupEventArgs e)
            {
                this.RootVisual = new MainPage() {DataContext = new TestViewModel1()
                                                                    {
                                                                        InnerContext = new TestViewModel2(){Message = "Hello World!"}
                                                                    }};
            }
    При запуске приложения отображается Hello World!
    • Предложено в качестве ответа Abolmasov DmitryModerator 27 июня 2012 г. 6:40
    • Помечено в качестве ответа YatajgaEditor 27 июня 2012 г. 8:46
    26 июня 2012 г. 21:02
  • Я все понял... Я все пытался проверить наличие контекста (заполненности DataContext) в конструкторе, а он там реально пуст и видимо инициируется позже.

    Ну еще и тупанул, так разместил поле для проверки есть ли какие то данные, что его не было видно. В общем проблема решена.

    Спасибо за помощь!

    • Помечено в качестве ответа YatajgaEditor 27 июня 2012 г. 8:46
    27 июня 2012 г. 8:34

Все ответы

  • Есть ли ошибки байндинга в Output window? MyContext поле или свойство?Если поле, то в какой момент оно инициализируется в ViewModel? Вызываете ли Вы при установке этого свойства/поля событие PropertyChanged?

    26 июня 2012 г. 20:40
  • Вот рабочий пример на скорую руку:

     public class TestViewModel1: INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
    
            private string _message;
            public string Message 
            {
                get
                {
                    return _message;
                }
                set
                {
                    if (_message!= value)
                    {
                        _message = value;
                        RaisePropertyChanged("Message");    
                    }
                } 
            }
    
            protected void RaisePropertyChanged(string propertyName)
            {
                if (PropertyChanged!= null)
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
    
            private TestViewModel2 _innerContext;
            public TestViewModel2 InnerContext
            {
                get { return _innerContext; }
                set
                {
                  if (_innerContext!= value)
                  {
                      _innerContext = value;
                      RaisePropertyChanged("InnerContext");    
                  }
                } 
            }
        }
    
    
        public class TestViewModel2 : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
    
            private string _message;
            public string Message
            {
                get
                {
                    return _message;
                }
                set
                {
                    if (_message != value)
                    {
                        _message = value;
                        RaisePropertyChanged("Message");
                    }
                }
            }
    
            protected void RaisePropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

    SilverlightControl1.xaml

    <UserControl x:Class="SilverlightApplication7.SilverlightControl1"
        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"
        mc:Ignorable="d"
        d:DesignHeight="300" d:DesignWidth="400">
        
        <Grid x:Name="LayoutRoot" Background="White">
            <TextBlock Text="{Binding Message}"/>
        </Grid>
    </UserControl>
    <UserControl x:Class="SilverlightApplication7.MainPage"
        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:SilverlightApplication7="clr-namespace:SilverlightApplication7" mc:Ignorable="d"
        d:DesignHeight="300" d:DesignWidth="400">
    
        <Grid x:Name="LayoutRoot" Background="White">
            <SilverlightApplication7:SilverlightControl1 DataContext="{Binding InnerContext}"/>
        </Grid>
    </UserControl>
    

    App.cs

     private void Application_Startup(object sender, StartupEventArgs e)
            {
                this.RootVisual = new MainPage() {DataContext = new TestViewModel1()
                                                                    {
                                                                        InnerContext = new TestViewModel2(){Message = "Hello World!"}
                                                                    }};
            }
    При запуске приложения отображается Hello World!
    • Предложено в качестве ответа Abolmasov DmitryModerator 27 июня 2012 г. 6:40
    • Помечено в качестве ответа YatajgaEditor 27 июня 2012 г. 8:46
    26 июня 2012 г. 21:02
  • Не забудьте отметить ответ, если он решит вашу проблему. Спасибо


    Для связи [mail]

    27 июня 2012 г. 6:40
    Модератор
  • Александр, ваш пример прекрасно работает и по идее у меня все сделано так же, MyContext - это свойство, инициализируется в конструкторе ViewModel. Ошибок биндинга нет, больше того, если разместить на форме стандартный контрол и связать его с этим свойством, то данные отображаются.
    27 июня 2012 г. 7:23
  • Покажите, пожалуйста, xaml и код UserControl, а также код ViewModel, где создается MyContext. Где-то закралась небольшая ошибка, т.к. все должно работать.

    27 июня 2012 г. 8:26
  • Как вариант, если Вы используете Silverlight 5, попробуйте подписаться на событие DataContextChanged у UserControl'a и поставить точку останова в обработчике события. Таким образом Вы сможете точно удостовериться, что DataContext у контора не обнуляется по каким-то причинам.


    27 июня 2012 г. 8:30
  • Я все понял... Я все пытался проверить наличие контекста (заполненности DataContext) в конструкторе, а он там реально пуст и видимо инициируется позже.

    Ну еще и тупанул, так разместил поле для проверки есть ли какие то данные, что его не было видно. В общем проблема решена.

    Спасибо за помощь!

    • Помечено в качестве ответа YatajgaEditor 27 июня 2012 г. 8:46
    27 июня 2012 г. 8:34
  • Не забывайте отмечать ответы решившие проблему.
    27 июня 2012 г. 8:47
    Модератор