WPF访问模板中的控件。 CalendarDayButton问题

时间:2013-06-05 17:37:31

标签: c# wpf templates controls

我正试图访问Control中的Template。为此,我重新定义了控件CalendarDayButton

<Window.Resources>
    <Style x:Key="myStyleDayButtonCalendar" TargetType="{x:Type CalendarDayButton}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type CalendarDayButton}">
                    <Grid  Name="gridCalendar">
                        <ContentControl Margin="5,1,5,1" Content="{TemplateBinding Content}"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>

<Grid x:Name="LayoutRoot" Background="White">
    <Calendar CalendarDayButtonStyle="{StaticResource myStyleDayButtonCalendar}" Name="myCalendar"  SelectedDatesChanged="Calendar_SelectedDatesChanged_1" />
</Grid>

没关系。但是当我想访问我的控制GRID时。不可能的:

private void Calendar_SelectedDatesChanged_1(object sender, SelectionChangedEventArgs e)
{
    Grid gridInTemplate = (Grid)myCalendar.Template.FindName("gridCalendar", myCalendar) as Grid;
}

我的网格是null。所以,我尝试了另一个Control。使用Button

<Window.Resources>
   <Style x:Key="myStyleButton" TargetType="{x:Type Button}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Grid  Name="myButton">
                        <Ellipse Fill="DarkBlue"></Ellipse>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>

<Grid x:Name="LayoutRoot" Background="White">
    <Calendar CalendarDayButtonStyle="{StaticResource myStyleDayButtonCalendar}" Name="myCalendar"  SelectedDatesChanged="Calendar_SelectedDatesChanged_1" />
    <Button Style="{StaticResource myStyleButton}" Name="myButton2" Margin="92,99,518,338" Click="myButton2_Click_1"></Button>
</Grid>

代码背后:

private void myButton2_Click_1(object sender, RoutedEventArgs e)
{
    Grid gridInTemplate = (Grid)myButton2.Template.FindName("myButton", myButton2);
}

此处gridInTemplate为NOT NULL。为什么在dayCalendarButton gridInTemplate为NULL的情况下呢?我想避免使用VisualTreeHelper

1 个答案:

答案 0 :(得分:0)

在您的情况下,您正试图在日历中找到CalendarDayButton。但这些是两个不同的控件。例如,我们有一个日历样式:

    <Style TargetType="{x:Type Calendar}">            
        <Setter Property="SnapsToDevicePixels" Value="True" />
        <Setter Property="BorderBrush" Value="Gray" />
        <Setter Property="BorderThickness" Value="1"/>

        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Calendar}">
                    <StackPanel x:Name="PART_Root" HorizontalAlignment="Center">
                        <CalendarItem x:Name="PART_CalendarItem" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" />
                    </StackPanel>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

在代码中我们可以像这样访问StackPanel:

    private void Calendar_SelectedDatesChanged(object sender, SelectionChangedEventArgs e)
    {
        StackPanel StackPanelInTemplate = (StackPanel)MyCalendar.Template.FindName("PART_Root", MyCalendar) as StackPanel;          
        MessageBox.Show(StackPanelInTemplate.Name);     
    }

但它在日历样式中不存在CalendarDayButton。这是一个单独的控制。在CalendarDayButton,我们只能获得样式:

Style MyCalendarDayButton = (Style)MyCalendar.CalendarDayButtonStyle;       

但不是模板。表格的构造:

CalendarDayButton MyCalendarDayButton = FindChild<CalendarDayButton>(MyCalendar, "gridCalendar");   

它无效。因为它与日历不在同一个可视树中而不起作用。

结论:也许只是访问CalendarDayButton是行不通的,因为它没有在日历的可视化树中看到(设计了这样的开发人员)。虽然我可能弄错了。使用DatePicker时遇到类似的问题。要访问DatePicker的某些部分是不可能的,例如:访问Watermark - http://matthamilton.net/datepicker-watermark

决定取决于你为什么需要这个按钮。尝试在Control,Style等触发器中移动你的功能,或者创建你自己的控件,继承自CalendarDayButton类(这很烦人)。我们使用转换器,例如:

<Grid x:Name="CalendarDayButtonGrid">                         
    <Grid.ToolTip>
          <MultiBinding Converter="{StaticResource HighlightDate}">
              <MultiBinding.Bindings>
                  <Binding />
                    <Binding RelativeSource="{RelativeSource FindAncestor, 
                               AncestorType={x:Type Calendar}}" />
              </MultiBinding.Bindings>
          </MultiBinding>
    </Grid.ToolTip>
    <!-- End addition -->
</Grid>

P.S。在这里您将被告知如何使用WPF ToolKit访问CalendarDayButton:http://codesticks.wordpress.com/tag/wpf-toolkit/