TextBlock
位于DataTemplate
,因此我无法通过其名称来引用它。那么如何以编程方式绑定其(例如)Text
属性?
XAML:
<UserControl x:Class="MyNameSpace.MyCustomControl" ... >
...
<ListBox ItemsSource="{Binding Path=ItemsSource}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
...
</UserControl>
代码:
public partial class MyCustomControl : UserControl {
...
public static readonly DependencyProperty DataSourceProperty =
DependencyProperty.Register("DataSource", typeof (IEnumerable),
typeof (MyCustomControl),
new PropertyMetadata(default(IEnumerable)));
public IEnumerable DataSource {
get { return (IEnumerable) GetValue(DataSourceProperty); }
set { SetValue(DataSourceProperty, value); }
}
public static readonly DependencyProperty MemberPathProperty =
DependencyProperty.Register("MemberPath", typeof (string),
typeof (MyCustomControl),
new PropertyMetadata(default(string)));
public string MemberPath {
get { return (string) GetValue(MemberPathProperty); }
set { SetValue(MemberPathProperty, value); }
}
...
public MyCustomControl() {
InitializeComponent();
var binding = new Binding(MemberPath);
BindingOperations.SetBinding(/*how do I refer to the TextBlock here ???*/,
TextBox.TextProperty, binding);
}
...
}
预期用法示例:
<my:MyCustomControl DataSource="{Binding Path=SomeModelCollection}" MemberPath="Name"
其中SomeModelCollection
是某些数据模型属性,例如ObservableCollection<SomeModel>
(SomeModel
有一个名为Name
的属性)
答案 0 :(得分:1)
您可以使用TextBlock
获取VisualTreeHelper
。此方法将为您提供listBoxItem的Visual树中存在的所有TextBlock:
public IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj)
where T : DependencyObject
{
if( depObj != null )
{
for( int i = 0; i < VisualTreeHelper.GetChildrenCount( depObj ); i++ )
{
DependencyObject child = VisualTreeHelper.GetChild( depObj, i );
if( child != null && child is T )
{
yield return (T)child;
}
foreach( T childOfChild in FindVisualChildren<T>( child ) )
{
yield return childOfChild;
}
}
}
}
用法:
TextBlock textBlock = FindVisualChildren<TextBlock>(listBoxItem)
.FirstOrDefault();
但我仍然建议在XAML中进行绑定,而不是在后面的代码中进行绑定。
如果ItemSource
为ObservableCollection<MyModel>
且MyModel
包含属性Name
,则可以在XAML中完成,如下所示:
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
由于DataContext
的{{1}}将为ListBoxItem
,因此您可以直接绑定到Name属性,如上所述。