2012-01-24 64 views
2

我剛剛陷入了一個問題,它將ItemsControl中的集合與包含有界組合框的ItemTeplate綁定在一起。在ItemTemplate中包含綁定組合框的ItemsControl

在我的場景中,我需要「生成」包含文本框和組合框中每個項目的組合框,並讓用戶更新項目。我可以使用DataGrid,但我希望在編輯模式下看到所有的行,所以我使用ItemsControl和自定義的ItemTemplate。

可以編輯文本框,但是當您嘗試更改任何ComboBox時,其他行中的所有其他ComboBoxes也會發生更改。 它是一個錯誤或功能?

此致的Ondrej

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

根據Rachel的答案,如果我設置ComboBox.IsSynchronizedWithCurrentItem我的解決方案將工作=「假」 – Ondrej

回答

3

我相信這是因爲你綁定了一個跟蹤當前項目的CollectionViewSource。嘗試直接綁定到你的列表,而不是,不會跟蹤當前項目

<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

對於ItemsSource技巧+1。任何方式使強類型如此intellisense作品? –

+0

@MikeCole不是我所知道的。您可以使用自定義標記擴展程序來做某些事情,但我認爲這會比嘗試構建:)更麻煩。 – Rachel

1

雖然你有每一行中的組合框,它不看到這些組合框作爲獨立。即它們都使用相同的集合,並且具有相同的selectedValue,所以當一個方框中的值發生變化時,它們都會發生變化。

解決此問題的最佳方法是將SampleItemType集合添加爲SampleItem模型的屬性,然後將組合框綁定到該屬性。