I really don't understand WPF and XAML, and inherited some terribly written code, so I may be butchering this, but here goes.
I inherited a DataGrid bound (in code behind) to a list of Person objects, where the necessary DataGridTextColumns are specified in XAML (presumably to allow styling).
<DataGrid x:Name="PersonGrid" ItemsSource="{Binding}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=LastName}" MaxWidth="Infinity" MinWidth="150" Header="Last Name">
<DataGridTextColumn Binding="{Binding Path=FirstName}" MaxWidth="Infinity" MinWidth="150" Header="First Name" />
<DataGridTextColumn Binding="{Binding Path=DOB, StringFormat=\{0:MM/dd/yyyy\}}" MaxWidth="Infinity" MinWidth="200" Header="Date of Birth (MM/DD/YYYY)" />
<DataGridTextColumn Binding="{Binding Path=Number}" MaxWidth="Infinity" MinWidth="150" Header="(P)erson Number" />
</DataGrid.Columns>
<DataGrid.DataContext>
<dm:Person />
</DataGrid.DataContext>
</DataGrid>
I would like to display just the person's last initial, optionally based on the state of a checkbox.
<CheckBox Name="ShowFullNames_CheckBox" Content="Show Full Names" IsChecked="False"/>
I was able to hook up a converter to the LastName Binding in code behind, but get an error ("Binding cannot be changed after it has been used.") when I try to change that converter after the data is bound.
I thought that maybe I could also bind the checkbox IsChecked state to the ConverterParameter or one binding of a Multibinding, but couldn't get that to work.
<DataGridTextColumn MaxWidth="Infinity" MinWidth="150" Header="Last Name">
<DataGridTextColumn.Binding>
<MultiBinding Converter="myStringTruncator">
<Binding Source="ShowFullNames_CheckBox" Path="IsChecked"/>
<Binding Path="LastName"/>
</MultiBinding>
</DataGridTextColumn.Binding>
</DataGridTextColumn>
In the Convert method of myStringTruncator, the first binding was just filled with DependencyProperty.UnsetValue, instead of the value of the checkbox.
There's probably a really simple way to do this that I'm not seeing. Any ideas?
You can add the Converter to the Binding in XAML.
<DataGridTextColumn Binding="{Binding Path=LastName, Converter={StaticResource YourConverter}"
MaxWidth="Infinity"
MinWidth="150"
Header="Last Name">
But for binding the state of the checkbox you would have to use something like this (untested)
<DataGridTextColumn Header="Last Name">
<DataGridTextColumn.Binding>
<MultiBinding Converter="{StaticResource NameAndCheckBoxMultiValueConverter}">
<Binding Path="LastName" />
<Binding ElementName="myCheckBox" Path="IsChecked" />
</MultiBinding>
</DataGridTextColumn.Binding>
</DataGridTextColumn>
And the converter:
using System;
using System.Globalization;
using System.Windows.Data;
namespace TestWpf
{
public class NameAndCheckBoxMultiValueConverter: IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
var lastName = values[0] as String;
if(lastName != null)
{
var isChecked = (bool)values[1];
if (isChecked)
{
return lastName.Substring(0,1);
}
return lastName;
}
return null;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
来源:https://stackoverflow.com/questions/22355609/how-can-i-dynamically-change-the-converter-on-datagridtextcolumn-binding-in-wpf