2017-08-27 17 views
0

で{NewItemPlaceholder}に対処するためにIConverterを使用することは、私のDataTemplateです:ここ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. 上記の表の空の行の1つをクリックして新しい行を追加しようとすると(「行を追加することはできますが)」「{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

バインディングコンバータは不要です。代わりに、リストボックスをCustumersコレクションをラップするCollectionViewSourceにバインドします。 CollectionViewSourceは、ソースコレクションからNewItemPlaceholder要素をスキップします。

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

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

また、バインディングのSelectedItemのためのコンバータを必要としません。バインドのプロパティを設定してください:

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

ありがとうございます。冗長な行を削除し、説明をよくしてください。テーブル内の新しい行を選択すると、コンバーターに関するバインディングエラーが発生します。 – JohnG79