Reputation: 1345
I have a binding list of Models and a DataGrid. Value can be of couple of data types (bool, double).
public class Model
{
public object Value { get; set; }
}
public void Initialize()
{
var models = new BindingList<Model>();
models.Add(new Model(){ Value = "hello"});
models.Add(new Model(){Value=true});
signals.ItemsSource = models;
}
I want to display the data in the data grid and I want to use textbox for numbers, but combo(true/false) for boolean values.So I implemented bool2string converter and DataTemplateSelector. In my example I have one text column and one template column displaying the same data. When I start the application the combo values are not initialized (nothing is selected). Once I start playing with values, everything works,the values are properly synchronized (if I change value in one column, it will propagate to the other column). Do you have any idea, what mistake I'm doing?
public class BoolToStringConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return ((bool)value == true) ? "true" : "false";
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var comboValue = (value as ComboBoxItem).Content.ToString();
return (String.Compare(comboValue, "true", StringComparison.InvariantCultureIgnoreCase) == 0);
}
}
public class DynamicDataTemplateSelector : DataTemplateSelector
{
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
var element = container as FrameworkElement;
var signal = item as Model;
if (element != null && signal != null)
{
if (signal.Value is bool)
return element.FindResource("BoolTemplate") as DataTemplate;
else
return element.FindResource("TextTemplate") as DataTemplate;
}
return null;
}
}
My xaml looks like following:
<Window.Resources>
<comboQuestion:DynamicDataTemplateSelector x:Key="DataTemplateSelector"/>
<comboQuestion:BoolToStringConverter x:Key="BoolToStringConverter"/>
</Window.Resources>
<Grid>
<DataGrid Grid.Row="1" Name="signals" AutoGenerateColumns="False" ItemsSource="{Binding}" >
<DataGrid.Resources>
<DataTemplate x:Key="BoolTemplate">
<ComboBox SelectedItem="{Binding Value, Converter={StaticResource BoolToStringConverter}, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">
<ComboBoxItem>true</ComboBoxItem>
<ComboBoxItem>false</ComboBoxItem>
</ComboBox>
</DataTemplate>
<DataTemplate x:Key="TextTemplate">
<TextBox Text="{Binding Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn Header="TextValue" Binding="{Binding Value}"/>
<DataGridTemplateColumn Header="DynamicValue" CellTemplateSelector="{StaticResource DataTemplateSelector}"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
EDIT: I tried to change the SelectedItem to SelectedValue and I also tried to change the Convert part of the converter to:
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var cbi = new ComboBoxItem();
cbi.Content = ((bool)value == true) ? "true" : "false";
return cbi;
}
however, the behavior remains the same.
Upvotes: 1
Views: 780
Reputation: 9713
You can convert a boolean to an index number using the following converter:
public class BooleanToIndexConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return ((bool)value == true) ? 0 : 1;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return ((int)value == 0) ? true : false;
}
}
Then bind to SelectedIndex on the ComboBox:
SelectedIndex="{Binding Value, Converter={StaticResource BooleanToIndexConverter}}
Upvotes: 1