Почему связанная с DataGridTextColumn привязка ObservableCollection не обновляется?
В моем XAML я определил DataGrid, содержащий DataGridTextXolumns. Все простые столбцы корректно обновляют источник (ObservableCollection), но не поле источника, которое является List<string>
поле. Что мне не хватает, чтобы определить в XAML?
<UserControl x:Class="MyTool.MyTabItem"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<ScrollViewer HorizontalScrollBarVisibility="Auto">
<DataGrid x:Name="notificationsGrid" ItemsSource="{Binding}"
AlternatingRowBackground="LightBlue" AutoGenerateColumns="False" CanUserAddRows="True" IsReadOnly="False"
SelectionMode="Single" BorderThickness="3" Unloaded="DataGrid_Unloaded" >
<DataGrid.Columns>
<DataGridTextColumn Header="Op" Binding="{Binding Mode=TwoWay, Path=Notification.Op}">
<DataGridTextColumn Header="DetailParams" Binding="{Binding Path=Notification.DetailParams, Mode=TwoWay,
Converter={StaticResource StringListConverter}, UpdateSourceTrigger=LostFocus}">
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</ScrollViewer>
</Grid>
</UserControl>
Обновление столбца "Op" работает нормально, но "DetailParams" - нет.
Вот код используемого StringToListConverter:
public class StringToListConverter : IValueConverter
{
/// <summary>
/// Converts a comma separated string into a List<string>.
/// </summary>
/// <param name="value"></param>
/// <param name="targetType"></param>
/// <param name="parameter"></param>
/// <param name="culture"></param>
/// <returns></returns>
object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if( value is string)
{
return value;
}
Console. WriteLine("DetailParams: " + string.Join(",", ((List<string>)value)));
return string.Join(",", (List<string>)value);
}
/// <summary>
/// Converts a List<string> into a comma separated string.
/// </summary>
/// <param name="value"></param>
/// <param name="targetType"></param>
/// <param name="parameter"></param>
/// <param name="culture"></param>
/// <returns></returns>
object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
Console.WriteLine(string.Join(",", value));
return string.Join(",", value);
}
}
Источник данных UserControl определяется следующим образом:
public partial class RawNotificationTabItem : UserControl//, INotifyPropertyChanged
{
private ObservableCollection<RawNotificationRowViewModel> _notifications { get; set; }
//public StringToBoolConverter StringToBoolConverter {
// get { return StringToBoolConverter; }
// set { StringToBoolConverter = value; }
//}
public RawNotificationTabItem(ObservableCollection<RawNotificationRowViewModel> rnvm)
{
_notifications = rnvm == null ? _notifications = new ObservableCollection<RawNotificationRowViewModel>() : rnvm;
this._notifications = rnvm;
DataContext = _notifications;
InitializeComponent();
}
...
}
1 ответ
Решение
Когда Notification.DetailParams
имеет тип List<string>
и вы хотите преобразовать его в один string
для отображения и редактирования конвертер должен выглядеть так:
public class StringListToStringConverter : IValueConverter
{
public object Convert(
object value, Type targetType, object parameter, CultureInfo culture)
{
return string.Join(",", (IEnumerable<string>)value);
}
public object ConvertBack(
object value, Type targetType, object parameter, CultureInfo culture)
{
return new List<string>(((string)value).Split(','));
}
}
Если вы измените тип свойства на IEnumerable<string>
, вы можете упростить метод ConvertBack для непосредственного возврата string[]
вернулся String.Split
:
public object ConvertBack(
object value, Type targetType, object parameter, CultureInfo culture)
{
return ((string)value).Split(',');
}