0

我想在运行时SomeProperty将绑定路径更改为另一个。并且 PropertyName 可以是任何字符串,所以我不能在它运行之前设置它。这个怎么做?

我尝试了“FindName”方法来查找tb1,但它不起作用。

部分代码:

<ListBox>
 <ListBox.ItemTemplate>
  <DataTemplate>
   <TextBox Name="tb1" Text="{Binding Path=SomeProperty}"/>
  </DataTemplate>
 </ListBox.ItemTemplate>
</ListBox>
4

2 回答 2

2

也许您只是在寻找“DisplayMemberPath”?

<ListBox ItemsSource="{Binding Items}" DisplayMemberPath="SomeProperty" />

您不能将它与 DataTemplates 混合,但在您的示例中,您并不真正需要它。

您可以为此属性创建普通绑定:

<StackPanel>
    <ListBox ItemsSource="{Binding Items}"
        DisplayMemberPath="{Binding ElementName=DisplayPathText, Path=Text}" />
    <TextBox Name="DisplayPathText" Text="SomeProperty" />
</StackPanel>
于 2019-08-23T04:20:41.317 回答
1

由于缺乏上下文,让我们尝试建立一个。

假设您的 ListBox 绑定到具有和属性的Person列表,初始绑定将是并且您希望在运行时单击按钮时将其更改为。FirstNameLastNameFirstNameLastName

这就是你可以实现它的方法。

看法

<ListBox Name="LstBx" ItemsSource="{Binding PersonList}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <TextBox Name="tb1" Text="{Binding Path=FirstName}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

<Button Click="Button_Click" Width="100" Height="20" Content="Change Binding"/>

代码隐藏

public List<Person> PersonList { get; set; } = new List<Person>
{
    new Person { FirstName = "ABC", LastName = "123" },
    new Person { FirstName = "DEF", LastName = "456" },
    new Person { FirstName = "GHI", LastName = "789" }
};

public MainWindow()
{
    InitializeComponent();
    DataContext = this;
}

private void Button_Click(object sender, RoutedEventArgs e)
{
    foreach (var person in PersonList)
    {
        var listBoxItem = LstBx.ItemContainerGenerator.ContainerFromItem(person);
        var contentPresenter = FindVisualChild<ContentPresenter>(listBoxItem);
        var target = contentPresenter.ContentTemplate.FindName("tb1", contentPresenter) as TextBox;

        if (target != null)
        {
            var binding = new Binding
            {
                // Remember each ListBoxItem's DataContext is the individual item 
                // in the list, not the list itself.
                Source = person, 
                Path = new PropertyPath(nameof(Person.LastName)),
                // Depends on what you need.
                //Mode = BindingMode.TwoWay,
                //UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
            };

            BindingOperations.SetBinding(target, TextBox.TextProperty, binding);
        }
    }
}

// Available from MSDN
private Child FindVisualChild<Child>(DependencyObject obj) where Child : DependencyObject
{
    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
    {
        var child = VisualTreeHelper.GetChild(obj, i);
        if (child != null && child is Child)
        {
            return (Child)child;
        }
        else
        {
            var childOfChild = FindVisualChild<Child>(child);

            if (childOfChild != null) { return childOfChild; }
        }
    }
    return null;
}
于 2019-08-23T04:07:00.130 回答