如何访问样式中定义的控件元素

时间:2011-09-16 08:39:51

标签: c# wpf silverlight

我有一个使用ScrollViewer的CustomControl。以下代码是一个以简单方式显示我的用例的示例:

<Style TargetType="controls:MyCustomControl">
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="controls:MyCustomControl">
        <Grid x:Name="LayoutRoot" Background="White">
          <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition Height="20"/>
            <RowDefinition Height="20"/>
          </Grid.RowDefinitions>
          <ScrollViewer x:Name="scrollViewer" Grid.Row="0"
                        Height="300" Width="400"
                        VerticalScrollBarVisibility="Auto" 
                        HorizontalScrollBarVisibility="Auto"
                        Style="{StaticResource ScrollViewerStyle}">
            <Canvas x:Name="outer" Width="400" Height="400"
                    Background="Red" Margin="50">
              <Canvas x:Name="inner" Background="Green" 
                      Width="400" Height="400">
                <Canvas.RenderTransform>
                  <ScaleTransform ScaleX="{Binding Value, ElementName=slider}"
                                  ScaleY="{Binding Value, ElementName=slider}"/>
                </Canvas.RenderTransform>
              </Canvas>
            </Canvas>
          </ScrollViewer>
        <Slider x:Name="slider" Minimum="0.1" Maximum ="10"
                Value="1" Grid.Row="2"/>
      </Grid>
    </ControlTemplate>
  </Setter.Value>
</Setter>

我遗漏了属于Slider.ValueChanged的不相关的CodeBehind。

在另一个问题中,我问How do I stick Controls inside of ScrollViewer。在这个答案中,我有了模拟ScrollViewer的想法。我在ScrollViewer中添加了一些元素,如答案中所示。例如,我的ScrollViewer中有一个新的Canvas:

<Canvas x:Name="canvas"/>

我需要在运行时访问此Canvas,因此在WPF中我创建了:

public class MyScrollViewer : ScrollViewer

我覆盖OnApplyTemplate并通过GetTemplateChild访问它。所以一切都完成了。

在SL中,由于ScrollViewer已密封,因此无法实现这种方式。

现在我正在寻找另一种获取访问权限的方法。我希望VisualTreeHelper会帮助我,但我没有得到Canvas。无论是在我的自定义控件的CodeBehind还是在我的MainPage的代码隐藏中(我使用我的控件)。

private void GetCanvas(DependencyObject dependencyObject)
  {
    int count = VisualTreeHelper.GetChildrenCount(dependencyObject);
    for (int i = 0; i < count; i++)
    {
      DependencyObject child = VisualTreeHelper.GetChild(dependencyObject);
      Canvas canvas = child as Canvas;
      if (canvas == null)
      {
        GetCanvas(child);
      }
      else
      {
        // Code here if found
      }
    }
  }

然后一位同事记得我,存在指令x:FieldModifier。我之前从未使用它,只是听说过它。我试一试。

x:FieldModifier="public"

但不知道它是否真的让我有可能从代码隐藏中获取,甚至更少。

那么,有没有什么方法可以在运行时在Silverlight中访问我的Canvas?也许WPF本身可能还有另一种解决方案,也适用于SL?

1 个答案:

答案 0 :(得分:1)

在Silverlight中,可以使用Silverlight工具包中的扩展方法GetVisualDescendants(DependencyObject)。以下应该工作......

  • 添加对System.Windows.Controls.Primitives
  • 的引用
  • 使用System.Windows.Controls.Primitives
  • 添加
  • 调用scrollViewer.GetVisualDescendants()。OfType()。FirstOrDefault(canvas =&gt; canvas.Name.Equals(“yourCanvasName”)