2017-08-27 90 views
0

这里是我的DataTemplate:使用IConverter应对{NewItemPlaceholder}在WPF/XAML/MVVM

<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> 

而且,这两个不同的“容器的:

<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> 

和应用程序:

enter image description here

  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'... 

我可以写一个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(); 
    } 
} 

,并绑定到个别项目中,XAML云一样的东西:

<TextBlock Text="{Binding Name, Converter={StaticResource PlaceholderConverter}}"/> 

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

+0

我假设你想添加新行? – Blacktempel

+0

是@Blacktempel ...我只是不知道我可以在哪里绑定转换器。 (底部显示是只读的。) – JohnG79

+0

我没有在代码中看到任何'IConverter' ...你能提供更多关于你如何使用它的细节吗? – Grx70

回答

3

您不需要绑定转换器。相反,将ListBox绑定到包装Custumers集合的CollectionViewSource。 CollectionViewSource从源集合中跳过NewItemPlaceholder元素。

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

... 
<ListBox ItemsSource="{Binding Source={StaticResource CustomersCVS}}"/> 

你也不必为的SelectedItem绑定一个转换器。只要设置绑定的TargetNullValue属性:

<DataGrid SelectedItem="{Binding SelectedCustomer, 
    TargetNullValue={x:Static CollectionView.NewItemPlaceholder}}" .../> 
+0

谢谢,+1删除冗余行并提供了一个很好的解释。提到转换器的绑定错误在选择表中的新行时仍然出现。 – JohnG79