使用IConverter处理WPF/XAML/MVVM中的{NewItemPlaceholder}

Joh*_*G79 4 c# wpf xaml mvvm

这是我的DataTemplate:

<UserControl.Resources>
    <converter:PlaceholderConverter x:Key="_placeholderConverter"/>

    <!-- Data(Display)Template for data objects of x:Type Customer-->
    <DataTemplate DataType="{x:Type model:Customer}">
        <!-- Customer Properties will be vertically stacked -->
        <ContentControl >
            <StackPanel>
                <TextBlock Text="{Binding FirstName}"/>
                <TextBlock Text="{Binding LastName}"/>
                <TextBlock Text="{Binding Phone}"/>
            </StackPanel>
        </ContentControl>
    </DataTemplate>
<UserControl.Resources>
Run Code Online (Sandbox Code Playgroud)

和两个不同的'容器':

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="25"/>
        <RowDefinition Height="100"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>

    <Button Grid.Row="0"
            Content="Delete"
            HorizontalAlignment="Left"
            VerticalAlignment="Top"
            Width="75"
            Command="{Binding DeleteCommand}"/>

    <DataGrid Grid.Row="1" 
              ItemsSource="{Binding Customers}" 
              SelectedItem="{Binding SelectedCustomer}" 
              AutoGenerateColumns="True"/>

    <ListBox 
        Grid.Row="2" 
        ItemsSource="{Binding Customers, Mode=OneWay}"/>
</Grid>
Run Code Online (Sandbox Code Playgroud)

和应用程序:

在此输入图像描述

  1. 如何删除{NewItemPlaceholder}?[完成,下面的解决方案].
  2. 如何防止在单击上表中的一个空行时提到"{NewItemPlaceholder}"的绑定错误,意图添加新行(我仍然可以添加行).

错误:

...Cannot convert '{NewItemPlaceholder}' from type 'NamedObject' to type 'CustomerExample.Model.Customer'...


...ConvertBack cannot convert value '{NewItemPlaceholder}' (type 'NamedObject'). BindingExpression:Path=SelectedCustomer; DataItem='CustomerViewModel'...
Run Code Online (Sandbox Code Playgroud)

我可以写一个IConverter实现,但是如何将它绑定到XAML?

提前致谢 :-)

以下是IConverter的实现:

public class PlaceholderConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value != null && value.ToString() == "{NewItemPlaceholder}")
            return DependencyProperty.UnsetValue;
        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
Run Code Online (Sandbox Code Playgroud)

并绑定到单个项目,XAML类似于:

<TextBlock Text="{Binding Name, Converter={StaticResource PlaceholderConverter}}"/>
Run Code Online (Sandbox Code Playgroud)

但我认为我需要将它"全局"添加到数据集合元素中,而不是添加到单个属性的绑定位置.

Cle*_*ens 7

您不需要绑定转换器.而是将ListBox绑定到CollectionViewSource包装Custumers集合的那个.CollectionViewSource从源集合中跳过NewItemPlaceholder元素.

<UserControl.Resources>
    ...
    <CollectionViewSource x:Key="CustomersCVS" Source="{Binding Customers}"/>
</UserControl.Resources>

...
<ListBox ItemsSource="{Binding Source={StaticResource CustomersCVS}}"/>
Run Code Online (Sandbox Code Playgroud)

您还不需要为SelectedItem绑定使用Converter.只需设置Binding的TargetNullValue属性:

<DataGrid SelectedItem="{Binding SelectedCustomer,
    TargetNullValue={x:Static CollectionView.NewItemPlaceholder}}" .../>
Run Code Online (Sandbox Code Playgroud)