Ссылки на элементы управления в ContentControl являются нулевыми на уровне родителей (страницы)

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

Например, скажем, созданный мной пользовательский класс, производный от ContentControl, называется MyGroupBox, и я пытаюсь использовать его внутри элемента управления Page:

<UserControl x:Class="MyApplication.MyUserControl">
   <local:MyGroupBox Title="Basic Information">
      <TextBox x:Name="MyTextBox" />
   </local:MyGroupBox>
</UserControl>

Когда я пытаюсь получить доступ к MyTextBox из кода страницы, переменная-член имеет значение null. Как лучше всего обойти этот сценарий, чтобы получить доступ к этим элементам управления, чтобы я мог использовать их в коде страницы?

Спасибо!

РЕДАКТИРОВАТЬ: Вот шаблон по умолчанию для элемента управления MyGroupBox

<Style TargetType="local:MyGroupBox">
    <Setter Property="Foreground" Value="#FF000000"/>
    <Setter Property="HorizontalContentAlignment" Value="Left"/>
    <Setter Property="VerticalContentAlignment" Value="Top"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:MyGroupBox">
                <Border BorderThickness="1" Margin="8,8,0,0">
                    <Border.BorderBrush>
                        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                            <GradientStop Color="#FF979797" Offset="0"/>
                            <GradientStop Color="#FFF1F1F1" Offset="1"/>
                        </LinearGradientBrush>
                    </Border.BorderBrush>
                    <StackPanel>
                        <Grid>
                            <Rectangle>
                                <Rectangle.Fill>
                                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                        <GradientStop Color="White" Offset="0"/>
                                        <GradientStop Color="#FFDFE2ED" Offset="1"/>
                                    </LinearGradientBrush>
                                </Rectangle.Fill>
                            </Rectangle>
                            <TextBlock Text="{TemplateBinding Title}" Margin="10,3,3,3" TextAlignment="Center" HorizontalAlignment="Left" />
                        </Grid>
                        <ContentPresenter Cursor="{TemplateBinding Cursor}" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                    </StackPanel>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>    

РЕДАКТИРОВАТЬ:

public MyUserControl()
{
    InitializeComponent();

    if (this.MyTextBox == null)
    {
        // MyTextBox is null at this point - is there a way to get 
        // the InitializeComponent method to find the control named MyTextBox when
        // it is inside of a ContentControl derived class?
        MessageBox.Show("MyTextBox is null");
    }
}

1 ответ

Решение

Позвольте мне показать вам, как это сделать, продемонстрировав шаги, которые я предпринял для проверки того, что вы опубликовали:

  • В Visual Studio создайте приложение Silverlight

  • Добавьте новый элемент в проект Silverlight, выбрав "Шаблон элемента управления Silverlight", назовите его "MyGroupBox".

  • Откройте Themes\Generic.xaml, который теперь будет создан. Он будет содержать стиль:

Generic.xaml:-

<Style TargetType="local:MyGroupBox">
   ...
</Style>
  • Замените весь контент контентом в вашем вопросе.

  • Изменить MyGroupBox.cs, изменить, чтобы наследовать от ContentControl и добавить Title свойство зависимости.

MyGroupBox.cs:-

public class MyGroupBox : ContentControl
{
    public MyGroupBox()
    {
        this.DefaultStyleKey = typeof(MyGroupBox);
    }

    #region public string Title

    public string Title
    {
        get { return GetValue(TitleProperty) as string; }
        set { SetValue(TitleProperty, value); }
    }

    public static readonly DependencyProperty TitleProperty =
            DependencyProperty.Register(
                    "Title",
                    typeof(string),
                    typeof(MyGroupBox),
                    new PropertyMetadata(null));
    #endregion public string Title

}
  • Откройте MainPage.Xaml добавить немного использования для MyGroupBox

В MainPage.xaml

<Grid x:Name="LayoutRoot">
    <StackPanel>
        <local:MyGroupBox Title="Test" HorizontalContentAlignment="Stretch">
            <TextBox x:Name="MyTextBox" />
        </local:MyGroupBox>
    </StackPanel>
</Grid>
  • Отредактируйте файл MainPage.xaml.cs, чтобы проверить, MyTextBox нулевой

    public MainPage()
    {
        InitializeComponent();
        MessageBox.Show((MyTextBox == null).ToString());
    }
    

Я получаю "False", InitializeComponent успешно нашел элемент с именем "MyTextBox".

Другие вопросы по тегам