Search code examples
wpfbindingdatatemplatetextblock

In WPF how to change a DataTemplate's Textblock's text binding in code?


I have a ListBox whose ItemsSource is bound to a list of objects. The Listbox has a ItemTemplate with a DataTemplate containing a TextBlock. The textblock's Text is bound to the object's Name property (i.e. Text="{Binding Name}").

I would like to provide a radio button to show different views of the same list. For example allow a user to toggle between the Name property and an ID property.

I found a SO answer for this at 2381740 but I also have border and a textbox style set in data template (see code below).

Is there anyway to just reset the Textblock binding? I don't want to have to recreate the entire datatemplate. Actually I'm not even sure how to do that, is there an easy way to translating xaml to code?.

Thanks Cody

<DataTemplate>
  <Border Margin="0 0 2 2"
          BorderBrush="Black"
          BorderThickness="3"
          CornerRadius="4"
          Padding="3">
      <TextBlock Style="{StaticResource listBoxItemStyle}"
                 Text="{Binding Name}" />
  </Border>
</DataTemplate>

Solution

  • Just make it simple for yourself and use two textblocks and hide one of them.

    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>
    

    Code behind:

    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"};
                }
            }
        }
    }