在WPF中如何在代码中更改DataTemplate的Textblock的文本绑定?

cod*_*ode 4 wpf binding textblock datatemplate

我有一个ListBox,其ItemsSource绑定到一个对象列表.Listbox有一个ItemTemplate,其中包含一个包含TextBlock的DataTemplate.文本块的Text绑定到对象的Name属性(即Text ="{Binding Name}").

我想提供一个单选按钮来显示同一列表的不同视图.例如,允许用户在Name属性和ID属性之间切换.

我在2381740找到了一个SO答案,但我也在数据模板中设置了边框和文本框样式(参见下面的代码).

反正只是重置Textblock绑定?我不想重新创建整个datatemplate.实际上我甚至不确定如何做到这一点,是否有一种简单的方法将xaml转换为代码?

谢谢科迪

<DataTemplate>
  <Border Margin="0 0 2 2"
          BorderBrush="Black"
          BorderThickness="3"
          CornerRadius="4"
          Padding="3">
      <TextBlock Style="{StaticResource listBoxItemStyle}"
                 Text="{Binding Name}" />
  </Border>
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)

Ray*_*rns 13

Wallstreet Programmer的解决方案适合您,因为您使用单选按钮.然而,有一个更普遍的解决方案,我认为我应该提及这个问题的未来读者.

您可以将DataTemplate更改为使用普通"{Binding}"

<DataTemplate x:Key="ItemDisplayTemplate">
  <Border ...> 
    <TextBlock ...
               Text="{Binding}" /> 
  </Border> 
</DataTemplate> 
Run Code Online (Sandbox Code Playgroud)

然后在代码中,您不必重新创建完整的DataTemplate.您所要做的就是重新创建:

<DataTemplate>
  <ContentPresenter Content="{Binding Name}" ContentTemplate="{StaticResource ItemDisplayTemplate}" />
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)

这很容易:

private DataTemplate GeneratePropertyBoundTemplate(string property, string templateKey)
{
  var template = FindResource(templateKey);
  FrameworkElementFactory factory = new FrameworkElementFactory(typeof(ContentPresenter)); 
  factory.SetValue(ContentPresenter.ContentTemplateProperty, template);
  factory.SetBinding(ContentPresenter.ContentProperty, new Binding(property)); 
  return new DataTemplate { VisualTree = factory }; 
} 
Run Code Online (Sandbox Code Playgroud)

如果您有许多属性,即使在单选按钮示例中,这也特别方便.


Wal*_*mer 7

只需让自己变得简单并使用两个文本块并隐藏其中一个.

XAML:

<Window x:Class="Test.Window1"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  Height="300" Width="300">

  <Window.Resources>
    <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
  </Window.Resources>

  <StackPanel>
    <RadioButton Name="nameRadioBtn" Content="Name" IsChecked="True"/>
    <RadioButton Name="lengthRadioBtn" Content="Length" />
    <ListBox
      ItemsSource="{Binding Path=Items}">
      <ListBox.ItemTemplate>
        <DataTemplate>
          <Border BorderBrush="Red" BorderThickness="1">
            <Grid>
              <TextBlock 
                Text="{Binding .}" 
                Visibility="{Binding Path=IsChecked, ElementName=nameRadioBtn, 
                  Converter={StaticResource BooleanToVisibilityConverter}}" />
              <TextBlock 
                Text="{Binding Path=Length}" 
                Visibility="{Binding Path=IsChecked, ElementName=lengthRadioBtn,
                  Converter={StaticResource BooleanToVisibilityConverter}}" />
            </Grid>
          </Border>
        </DataTemplate>
      </ListBox.ItemTemplate>
    </ListBox>
  </StackPanel>        
</Window>
Run Code Online (Sandbox Code Playgroud)

代码背后:

using System.Collections.Generic;
using System.Windows;

namespace Test
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();

            DataContext = this;
        }

        public IEnumerable<string> Items
        {
            get
            {
                return new List<string>() {"Bob", "Sally", "Anna"};
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)