为什么DataGridTextColumn的绑定的ObservableCollection不更新?

时间:2019-01-06 10:12:29

标签: c# wpf xaml datagridtextcolumn

在我的XAML中,我定义了一个包含DataGridTextXolumns的DataGrid。所有 simple 列都会很好地更新源(ObservableCollection),但不会更新List<string>字段的source字段。我在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 个答案:

答案 0 :(得分: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(',');
}