作为这个问题的后续内容,建议我使用ContentControl,当我使用从ContentControl在页面上进行定制的自定义类时,我遇到了一个场景,无法从页面访问ContentControl中定义的任何控件。 所有成员变量都为null。
对于Instance,我说从ContentControl派生的自定义类名为MyGroupBox ,我尝试在Page控件中使用它:
<UserControl x:Class="MyApplication.MyUserControl"> <local:MyGroupBox Title="Basic Information"> <TextBox x:Name="MyTextBox" /> </local:MyGroupBox> </UserControl>当我尝试从后面的Page的代码中访问MyTextBox时,成员变量为null。 这个场景的最佳解决方法是什么才能访问这些控件,以便我可以在Page的代码中使用它们?
谢谢!
编辑:这是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"); } }最满意答案
让我通过展示我为测试你发布的内容而采取的步骤,一步一步地把它放在一起: -
在Visual Studio中创建Silverlight应用程序
在Silverlight项目中添加一个新项目,选择“Silverlight Templated Control”,调用此“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是否为null
public MainPage() { InitializeComponent(); 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 MyGroupBoxIn 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".
更多推荐
发布评论