wpf 如何获取内容控件内的元素
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19904989/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to Get element inside the content control
提问by Aleksey
I need to find the element inside the content control :
我需要在内容控件中找到元素:
<ContentControl Content="{Binding YourChoices}" Grid.ColumnSpan="3" x:Name="ccBloodGroup">
<ContentControl.ContentTemplate>
<DataTemplate>
<Grid>
<ComboBox x:Name="cbBloodGroup" ItemsSource="{Binding}" HorizontalAlignment="Left" Margin="10,160,0,0" VerticalAlignment="Top" Width="331" Height="45">
<ComboBoxItem>A+</ComboBoxItem>
<ComboBoxItem>A-</ComboBoxItem>
<ComboBoxItem>B+</ComboBoxItem>
<ComboBoxItem>B-</ComboBoxItem>
<ComboBoxItem>O+</ComboBoxItem>
<ComboBoxItem>O-</ComboBoxItem>
<ComboBoxItem>AB+</ComboBoxItem>
<ComboBoxItem>AB-</ComboBoxItem>
</ComboBox>
<TextBlock x:Name="tb" Text=" Blood Type" IsHitTestVisible="False" Visibility="Hidden" HorizontalAlignment="Left" Margin="10,176,0,0" VerticalAlignment="Top"/>
</Grid>
<DataTemplate.Triggers>
<Trigger SourceName="cbBloodGroup" Property="SelectedItem" Value="{x:Null}">
<Setter TargetName="tb" Property="Visibility" Value="Visible"/>
</Trigger>
</DataTemplate.Triggers>
</DataTemplate>
</ContentControl.ContentTemplate>
</ContentControl>
I found an answer on Internet as
我在互联网上找到了一个答案
ComboBox cb = ccBloodGroup.ContentTemplate.FindName("cbBloodGroup", ccBloodGroup) as ComboBox;
But this is giving me an run time exception saying 'This operation is valid only on elements that have this template applied.'
但这给了我一个运行时异常,说“此操作仅对应用了此模板的元素有效。”
Please help..
请帮忙..
回答by Aleksey
This method will help you:
此方法将帮助您:
public T FindElementByName<T>(FrameworkElement element, string sChildName) where T : FrameworkElement
{
T childElement = null;
var nChildCount = VisualTreeHelper.GetChildrenCount(element);
for (int i = 0; i < nChildCount; i++)
{
FrameworkElement child = VisualTreeHelper.GetChild(element, i) as FrameworkElement;
if (child == null)
continue;
if (child is T && child.Name.Equals(sChildName))
{
childElement = (T)child;
break;
}
childElement = FindElementByName<T>(child, sChildName);
if (childElement != null)
break;
}
return childElement;
}
And, how I use it, just add button, and on button Click:
而且,我如何使用它,只需添加按钮,然后单击按钮:
private void Button_OnClick(object sender, RoutedEventArgs e)
{
var element = FindElementByName<ComboBox>(ccBloodGroup, "cbBloodGroup");
}
回答by Sheridan
Basically, you need to provide an element that (as the error says) has the Templateapplied. Your ccBloodGroupcontrol is inside the DataTemplateand so clearly, does not have this Templateapplied to it.
基本上,您需要提供一个元素(如错误所述)已Template应用。你的ccBloodGroup控制在里面DataTemplate,所以很明显,没有Template应用到它。
For example, an element that might have this Templateapplied to it would be the ContentPresenters of the items in the YourChoicescollection that are using this DataTemplateto define what they look like in the UI.
例如,一个可能Template应用this 的元素将是集合中使用 this来定义它们在 UI 中的外观ContentPresenter的项目的s 。YourChoicesDataTemplate
You can find out full details as usual on MSDN, with a detailed example on the FrameworkTemplate.FindNameMethodpage, but it goes something like this... from the example on the linked page:
你可以像往常一样在 MSDN 上找到完整的细节,在FrameworkTemplate.FindName方法页面上有一个详细的例子,但它是这样的......来自链接页面上的例子:
// Getting the currently selected ListBoxItem
// Note that the ListBox must have
// IsSynchronizedWithCurrentItem set to True for this to work
ListBoxItem myListBoxItem = (ListBoxItem)(myListBox.ItemContainerGenerator.
ContainerFromItem(myListBox.Items.CurrentItem));
// Getting the ContentPresenter of myListBoxItem
ContentPresenter myContentPresenter = FindVisualChild<ContentPresenter>(myListBoxItem);
// Finding textBlock from the DataTemplate that is set on that ContentPresenter
DataTemplate myDataTemplate = myContentPresenter.ContentTemplate;
TextBlock myTextBlock = (TextBlock)myDataTemplate.FindName("textBlock",
myContentPresenter);
// Do something to the DataTemplate-generated TextBlock
MessageBox.Show("The text of the TextBlock of the selected list item: "
+ myTextBlock.Text);
The
FindVisualChildmethod is shown on the linked page.
该
FindVisualChild方法显示在链接页面上。

