Ham*_*mza 2 c# wpf visual-studio-2010 wpf-controls
关于 WPF 的一个快速问题:如何在画布/网格中选择子元素?
例如,在以下 XAML 代码段中:
<Canvas Name="parentCanvas" Width="200" Height="200" Background="AliceBlue" MouseMove="parentCanvas_MouseMove" MouseLeave="parentCanvas_MouseLeave">
<Border Name="border1" Margin="10" Height="100" Width="180" Background="Maroon" Canvas.Top="47" />
</Canvas>
Run Code Online (Sandbox Code Playgroud)
...如何访问border1内部parentCanvas_MouseMove和parentCanvas_MouseLeave方法?
此外,我在事件处理程序中访问画布本身的方式看起来有点古怪,我做了一些事情:
private void parentCanvas_MouseLeave(object sender, MouseEventArgs e)
{
Canvas c = (Canvas)sender;
c.Background = Brushes.Blue;
}
Run Code Online (Sandbox Code Playgroud)
这是访问它的正确方式还是有更优雅的方式来做到这一点?
非常感谢,
哈姆扎。
当您使用Name属性命名控件时,它将在类中生成一个成员,因此您应该能够通过名称访问它们:
private void parentCanvas_MouseLeave(object sender, MouseEventArgs e)
{
Canvas c = parentCanvas;
c.Background = Brushes.Blue;
Border b = border1;
}
Run Code Online (Sandbox Code Playgroud)
如果控件是 ControlTemplate 或 DataTemplate 的一部分,则您需要获取对父项的引用并在模板中查找它。例如,如果您的 XAML 是 DataTemplate 的一部分,则必须执行以下操作:
private void parentCanvas_MouseLeave(object sender, MouseEventArgs e)
{
Canvas c = (Canvas)sender;
var contentPresenter = (ContentPresenter)c.TemplatedParent;
var b = contentPresenter.ContentTemplate.FindName(
"border1", contentPresenter);
}
Run Code Online (Sandbox Code Playgroud)
在任何情况下,将sender参数转换为适当的类型是完全合理的,它可以让您的事件处理程序更可重用。
如果您的画布没有名称,您还可以使用画布的Children属性来遍历其视觉子级:
private void parentCanvas_MouseLeave(object sender, MouseEventArgs e)
{
Canvas c = (Canvas)sender;
var firstChild = c.Children[0];
var firstBorderChild = c.Children.OfType<Border>().FirstOrDefault();
}
Run Code Online (Sandbox Code Playgroud)
最后,如果您的视觉对象不是面板,则可以使用VisualTreeHelper.GetChildrenCount和VisualTreeHelper.GetChild:
for (int childIndex = 0;
childIndex < VisualTreeHelper.GetChildrenCount(c);
childIndex++)
{
var child = VisualTreeHelper.GetChild(c, childIndex);
}
Run Code Online (Sandbox Code Playgroud)