对 ContentControl 中控件的引用在父级(页面)级别为空

发布于 2024-09-10 18:50:38 字数 3247 浏览 0 评论 0原文

作为这个问题的后续建议我使用ContentControl,当我使用从页面上的 ContentControl 派生的自定义类时,我遇到了这样的情况:无法从页面访问该 ContentControl 中定义的任何控件。所有成员变量都为空。

例如,假设我创建的派生自 ContentControl 的自定义类名为 MyGroupBox,我尝试在页面控件中使用它

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

: Page的代码后面,成员变量为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");
    }
}

As a follow up to this question where it was suggested I use a ContentControl, I have run into a scenario when I use a custom made class that dervies from ContentControl on a page, any controls defined within that ContentControl are not accessible from the page. All member variables turn out null.

For Instance, say the custom class I created that derives from ContentControl is named MyGroupBox and I try to use this inside a Page control:

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

When I try to access MyTextBox from within the Page's code behind, the member variable is null. What is the best workaround for this scenario to get access to these controls so that I can use them in the Page's code behind?

Thanks!

EDIT:
Here is the Default Template for the MyGroupBox control

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

EDIT:

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");
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

千柳 2024-09-17 18:50:38

让我通过展示我测试您发布的内容所采取的步骤来逐步将其组合在一起:-

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

}
  • 添加 MyGroupBox 的一些用法

打开 MainPage.Xaml在 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 是否为 null

    公共 MainPage()
    {
        初始化组件();
        MessageBox.Show((MyTextBox == null).ToString());
    }
    

我得到“False”,InitializeComponent 已成功找到名为“MyTextBox”的元素。

Let me step you through putting it together by showing the steps I took to test what you posted:-

  • In Visual Studio create a Silverlight Application

  • Add a new item to the Silverlight project selecting "Silverlight Templated Control", call this "MyGroupBox".

  • Open the Themes\Generic.xaml which will now have been created. It will contain the a style:-

Generic.Xaml:-

<Style TargetType="local:MyGroupBox">
   ...
</Style>
  • Replace its entire content with the content in your question.

  • Edit MyGroupBox.cs, modify to inherit from ContentControl and add Title dependency property.

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

}
  • Open MainPage.Xaml add some usage for MyGroupBox

In MainPage.xaml

<Grid x:Name="LayoutRoot">
    <StackPanel>
        <local:MyGroupBox Title="Test" HorizontalContentAlignment="Stretch">
            <TextBox x:Name="MyTextBox" />
        </local:MyGroupBox>
    </StackPanel>
</Grid>
  • Edit the MainPage.xaml.cs to test whether MyTextBox is null

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

I get "False", InitializeComponent has succesfully found the element with the name "MyTextBox".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文