2012-01-12 35 views
0

相对的WPF新手,这可能会有一个简单的解决方案(我希望!)。我有两个属性的类:访问内容模板中的控件的方法

public class MyClass 
{ 
    public String Name { get; set; } 
    public String Description { get; set; } 
} 

我有具有正文块和一个按钮的用户控制:正文块显示文本(明显)和所述按钮用于任一加粗或取消粗体文本的文本块:

MyControl.xaml:

<UserControl 
    x:Class="WpfApplication1.MyControl" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    mc:Ignorable="d" 
    d:DesignHeight="300" 
    d:DesignWidth="300" 
    xmlns:this="clr-namespace:WpfApplication1"> 
    <Grid> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="*" /> 
      <ColumnDefinition Width="48" /> 
     </Grid.ColumnDefinitions> 

     <TextBlock 
      x:Name="txtDescription" 
      Grid.Column="0" 
      Text="{Binding Path=Description, RelativeSource={RelativeSource AncestorType={x:Type this:MyControl}}}" /> 

     <Button 
      x:Name="btnBold" 
      Grid.Column="1" 
      Content="Bold" 
      Click="btnBold_Click" /> 
    </Grid> 
</UserControl> 

MyControl.xaml.cs:

public partial class MyControl : UserControl 
{ 
    public static readonly DependencyProperty DescriptionProperty = DependencyProperty.Register("Description", typeof(String), typeof(MyControl)); 

    public String Description 
    { 
     get { return GetValue(MyControl.DescriptionProperty) as String; } 
     set { SetValue(MyControl.DescriptionProperty, value); } 
    } 

    public MyControl() 
    { 
     InitializeComponent(); 
    } 

    private void btnBold_Click(object sender, RoutedEventArgs e) 
    { 
     ToggleBold(); 
    } 

    public void ToggleBold() 
    { 
     if (txtDescription.FontWeight == FontWeights.Bold) 
     { 
      btnBold.Content = "Bold"; 
      txtDescription.FontWeight = FontWeights.Normal; 
     } 
     else 
     { 
      btnBold.Content = "Unbold"; 
      txtDescription.FontWeight = FontWeights.Bold; 
     } 
    } 
} 

在我的主窗口中,我有一个选项卡控件,它具有项目模板(在每个选项卡的标题中显示MyClass.Name)和内容模板。内容模板包含我上面的控制之一,MyClass.Description势必MyControl.Description:

MainWindow.xaml:

<Window 
    x:Class="WpfApplication1.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" 
    Height="350" 
    Width="525" 
    xmlns:this="clr-namespace:WpfApplication1"> 
    <Grid> 
     <TabControl x:Name="tabItems"> 
      <TabControl.ItemTemplate> 
       <DataTemplate> 
        <TextBlock Text="{Binding Name}" /> 
       </DataTemplate> 
      </TabControl.ItemTemplate> 

      <TabControl.ContentTemplate> 
       <DataTemplate> 
        <this:MyControl 
         Description="{Binding Description}" /> 
       </DataTemplate> 
      </TabControl.ContentTemplate> 
     </TabControl> 
    </Grid> 
</Window> 

MainWindow.xaml.cs:

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 

     List<MyClass> myClasses = new List<MyClass>(); 
     myClasses.Add(new MyClass() { Name = "My Name", Description = "My Description" }); 
     myClasses.Add(new MyClass() { Name = "Your Name", Description = "Your Description" }); 

     tabItems.ItemsSource = myClasses; 
    } 
} 

当程序运行我将两个类型为MyClass的对象添加到列表中,将列表设置为Tab控件的ItemsSource属性,并且它完全正常工作:我得到两个带有“我的名字”和“您的姓名”作为标题的选项卡,说明显示在正确的位置,按钮将打开或关闭粗体rrectly。

我的问题是,如何添加标签控件的一个按钮,置身其中可以调用MyControl对象,它是在选择项目的内容模板的MyControl.ToggleBold方法:

MainWindow.xaml :

<Window 
    x:Class="WpfApplication1.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" 
    Height="350" 
    Width="525" 
    xmlns:this="clr-namespace:WpfApplication1"> 
    <Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="*" /> 
      <RowDefinition Height="Auto" />    
     </Grid.RowDefinitions> 

     <TabControl x:Name="tabItems" Grid.Row="0"> 
      <TabControl.ItemTemplate> 
       <DataTemplate> 
        <TextBlock Text="{Binding Name}" /> 
       </DataTemplate> 
      </TabControl.ItemTemplate> 

      <TabControl.ContentTemplate> 
       <DataTemplate> 
        <this:MyControl 
         x:Name="myControl" 
         Description="{Binding Description}"/> 
       </DataTemplate> 
      </TabControl.ContentTemplate> 
     </TabControl> 

     <Button Grid.Row="1" Content="Toggle Selected Tab" Click="Button_Click" /> 
    </Grid> 
</Window> 

MainWindow.xaml.cs:

... 

private void Button_Click(object sender, RoutedEventArgs e) 
{ 
    MyClass myClass = tabItems.SelectedItem as MyClass; 
    MyControl myControl; 

    ///get the instance of myControl that is contained 
    ///in the content template of tabItems for the 
    ///myClass item 

    myControl.ToggleBold(); 
} 

... 

我知道我可以通过调用tabItems.SelectedContentTemplate访问数据模板,但一就我所知,我无法访问模板中的控件(我认为我也不应该这样做)。有FindName方法,但我不知道通过作为templatedParent参数。

任何帮助将非常感激。

+1

你有没有考虑使用MVVM来实现这一功能? – 2012-01-12 15:49:57

回答

0

您可以导航VisualTree找到您要查找的控件。

例如,我用一组custom VisualTreeHelpers这将允许我这样称呼是这样的:

var myControl = VisualTreeHelpers.FindChild<MyControl>(myTabControl); 
if (myControl != null) 
    myControl.ToggleBold(); 
+0

作品。谢谢! – 2012-01-13 08:36:03