为什么 DataGridTextColumn 的绑定 ObservableCollection 没有更新?
Why is DataGridTextColumn's bound ObservableCollection is not updated?
在我的 XAML 中,我定义了一个包含 DataGridTextXolumns 的 DataGrid。所有 simple 列都能很好地更新源 (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的DataSource定义如下:
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();
}
...
}
当 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 方法简化为直接 return string[]
return 由 String.Split
:
public object ConvertBack(
object value, Type targetType, object parameter, CultureInfo culture)
{
return ((string)value).Split(',');
}
在我的 XAML 中,我定义了一个包含 DataGridTextXolumns 的 DataGrid。所有 simple 列都能很好地更新源 (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的DataSource定义如下:
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();
}
...
}
当 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 方法简化为直接 return string[]
return 由 String.Split
:
public object ConvertBack(
object value, Type targetType, object parameter, CultureInfo culture)
{
return ((string)value).Split(',');
}