2012-01-24 4 views
2

バインドされたComboBoxを含むItemTeplateでItemsControlのコレクションをバインドする際に問題が発生しました。ItemsControl ItemTemplateでバインドされたComboBoxを含む

私のシナリオでは、コレクションの各アイテムのテキストボックスとコンボボックスを含むフォームを生成し、ユーザーにアイテムを更新させる必要があります。私はそれにDataGridを使用することができましたが、編集モードですべての行を表示したいので、ItemControlをカスタムItemTemplateとともに使用します。

テキストボックスを編集しても構いませんが、コンボボックスを変更しようとすると、他の行の他のコンボボックスもすべて変更されます。 バグですか?または機能ですか?

おかげで、オンドレイ

Window.xaml

<Window x:Class="ComboInItemsControlSample.Window1" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
Title="Window1" Height="480" Width="640"> 
<Window.Resources> 

    <CollectionViewSource x:Key="cvsComboSource" 
     Source="{Binding Path=AvailableItemTypes}" /> 

    <DataTemplate x:Key="ItemTemplate"> 
     <Border BorderBrush="Black" BorderThickness="0.5" Margin="2"> 
      <Grid Margin="3"> 
       <Grid.ColumnDefinitions> 
        <ColumnDefinition Width="1*" /> 
        <ColumnDefinition Width="20" /> 
        <ColumnDefinition Width="1*" /> 
       </Grid.ColumnDefinitions> 

       <TextBox Grid.Column="0" Text="{Binding Path=ItemValue}" /> 
       <ComboBox Grid.Column="2" 
          SelectedValue="{Binding Path=ItemType}" 
          ItemsSource="{Binding Source={StaticResource cvsComboSource}}" 
          DisplayMemberPath="Name" 
          SelectedValuePath="Value" /> 
      </Grid> 
     </Border> 
    </DataTemplate> 

</Window.Resources> 
<Grid> 

    <ItemsControl ItemsSource="{Binding Path=SampleItems}" 
        ItemTemplate="{StaticResource ItemTemplate}" 
        Margin="10" /> 

</Grid> 

Window.xaml.cs

public partial class Window1 : Window 
{ 
    public Window1() 
    { 
     InitializeComponent(); 

     DataContext = new ViewModel(); 
    } 
} 

public class ViewModel 
{ 
    public ViewModel() 
    { 
     SampleItems = new List<SampleItem> { 
      new SampleItem { ItemValue = "Value 1" }, 
      new SampleItem { ItemValue = "Value 2" }, 
      new SampleItem { ItemValue = "Value 3" } 
     }; 

     AvailableItemTypes = new List<SampleItemType> { 
      new SampleItemType { Name = "Type 1", Value = 1 }, 
      new SampleItemType { Name = "Type 2", Value = 2 }, 
      new SampleItemType { Name = "Type 3", Value = 3 }, 
      new SampleItemType { Name = "Type 4", Value = 4 } 
     }; 
    } 

    public IList<SampleItem> SampleItems { get; private set; } 
    public IList<SampleItemType> AvailableItemTypes { get; private set; } 
} 

public class SampleItem : ObservableObject 
{ 
    private string _itemValue; 
    private int _itemType; 

    public string ItemValue 
    { 
     get { return _itemValue; } 
     set { _itemValue = value; RaisePropertyChanged("ItemValue"); } 
    } 
    public int ItemType 
    { 
     get { return _itemType; } 
     set { _itemType = value; RaisePropertyChanged("ItemType"); } 
    } 
} 

public class SampleItemType : ObservableObject 
{ 
    private string _name; 
    private int _value; 

    public string Name 
    { 
     get { return _name; } 
     set { _name = value; RaisePropertyChanged("Name"); } 
    } 
    public int Value 
    { 
     get { return _value; } 
     set { _value = value; RaisePropertyChanged("Value"); } 
    } 
} 

public abstract class ObservableObject : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 
    protected void RaisePropertyChanged(string propertyName) { 
     var handler = PropertyChanged; 
     if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

ピクチャー

here you can see the result on picture

+1

を追跡しません。これは、代わりにあなたのリストに直接結合してみてください、私の解決策はうまくいく=「false」を – Ondrej

答えて

3

あなたは現在のアイテムを追跡するCollectionViewSourceに拘束していると思います。私はComboBox.IsSynchronizedWithCurrentItemを設定した場合、レイチェルの回答によると、現在の項目

<ComboBox Grid.Column="2" 
      SelectedValue="{Binding Path=ItemType}" 
      DisplayMemberPath="Name" 
      SelectedValuePath="Value" 
      ItemsSource="{Binding RelativeSource={ 
       RelativeSource AncestorType={x:Type ItemsControl}}, 
       Path=DataContext.AvailableItemTypes}" /> 
+0

まあ、私は馬鹿です、あなたはもちろんです:-)目を開けてくれてありがとう:-)。時には私は明白なことを見ない。 – Ondrej

+0

+1 ItemsSourceトリック。それを強く型付けしてインテリセンスを動作させる方法はありますか? –

+0

@MikeCole私が知っているわけではありません。カスタマイズしたマークアップ拡張機能を使って何かをすることができるかもしれませんが、それは試してビルドする価値があるよりも面倒です – Rachel

1

あなたは各行のコンボボックスを持っているが、それは別々のものとしてこれらのコンボボックスを参照してくださいdoesntの。つまり、それらはすべて同じコレクションと同じselectedValueを使用しているため、値が1つのボックス内で変更されると、そのすべてが変更されます。

この問題を解決する最善の方法は、SampleItemモデルのプロパティとしてSampleItemTypeコレクションをプロパティとして追加し、そのプロパティにコンボボックスをバインドすることです。

関連する問題