2013-03-15 293 views
1

我在MVVM的選項卡項中有一個組合框。這個選項卡可以在我的應用程序中創建多次(相同的視圖,相同的視圖模型,但不同的實例),所以我可以從一個選項卡切換到另一個(但它們是相同類型的選項卡)。WPF組合框選擇更改TabItem選擇更改

它適用於每個WPF控件,但與組合框我有一個奇怪的行爲: 焦點選項卡,當它失去焦點時,獲取應用程序正在關注的選項卡的選擇項目。

如果我從2個不是相同類型的標籤切換一切正常,任何想法呢?謝謝。

XAML:

<CollectionViewSource x:Key="StatusView" Source="{Binding Path=StatusList}"/> 
<ComboBox Name="_spl2Status" Grid.Column="3" Grid.Row="0" 
      ItemsSource="{Binding Source={StaticResource StatusView}}" 
      SelectedValue="{Binding Path=CurrentSPL2.ID_SPL2_STATUS, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
      SelectedValuePath="FL_TYPE" 
      DisplayMemberPath="ID_TYPE"> 
</ComboBox> 

VM:

public List<NullableByteEnumType> StatusList 
{ 
    get 
    { 
     return (SPC_SPL2.SPL2StatusCollection.Skip(1)).ToList(); 
    } 
} 

private SPC_SPL2 _currentSPL2 = null; 

public SPC_SPL2 CurrentSPL2 
{ 
    get 
    { 
     if (_currentSPL2== null) 
      Controller.Execute(delegate(IResult result) 
      { 
       Dictionary<string, object> parameters = new Dictionary<string, object>(); 
       parameters.Add("FL_ACTIVE", true); 
       parameters.Add("ID_SPL2", _itemcode); 
       Model.Invalidate(typeof(SPC_SPL2), Filter.GENERIC<SPC_SPL2>(parameters, "ID_SPL2")); 
       Model.Include<SPC_SPL2>(); 

       if (Model.Appendload(result) == false) 
        return false; 

       Debug.Assert(Context.SPC_SPL2.Count == 1); 
       _currentSPL2= Context.SPC_SPL2.FirstOrDefault(); 

       return result.Successful; 
      }); 

     return _currentSPL2; 
    } 
    set 
    { 
     _currentSPL2= value; 
     OnPropertyChanged(() => CurrentSPL2); 
    } 
} 

我的標籤都以這種方式處理:

<Grid> 
    <Border Grid.Row="0"> 
     <ContentControl 
      Content="{Binding Path=Workspaces}" 
      ContentTemplate="{StaticResource MasterWorkspacesTemplate}" 
      /> 
    </Border> 
</Grid> 

其中

<DataTemplate x:Key="MasterWorkspacesTemplate"> 
      <TabControl IsSynchronizedWithCurrentItem="True" 
         BorderThickness="0" 
         ItemsSource="{Binding}" 
         SelectedItem="{Binding}" 
         ItemContainerStyleSelector="{StaticResource TabItemTemplate}" 
         /> 
     </DataTemplate> 

和工作空間(我的ViewModels名單)(T是誰從viewModelBase繼承一個類)

public T CurrentWorkspace 
    { 
     get { return WorkspacesView.CurrentItem as T; } 
    } 

    private ObservableCollection<T> _workspaces; 
    public ObservableCollection<T> Workspaces 
    { 
     get 
     { 
      if (_workspaces == null) 
      { 
       _workspaces = new ObservableCollection<T>(); 
       _workspaces.CollectionChanged += _OnWorkspacesChanged; 
      } 

      return _workspaces; 
     } 
    } 
    protected ICollectionView WorkspacesView 
    { 
     get 
     { 
      ICollectionView collectionView = CollectionViewSource.GetDefaultView(Workspaces); 
      Debug.Assert(collectionView != null); 
      return collectionView; 
     } 
    } 
+0

PL s,用'ComboBox'和綁定的VM添加視圖的一些代碼。 – DHN 2013-03-15 09:46:13

+0

我添加了一些代碼,在此先感謝您的幫助 – andrea 2013-03-15 09:58:19

+0

您可以展示如何初始化視圖模型以及您使用的是什麼MVVM框架? – 2013-03-15 14:52:45

回答

0

你真的確認你正在創建的視圖模型的新實例。如果不是,那麼組合框共享相同的collectionviewsource,這意味着一個組合框中的更改將反映在所有組合框中。我自己也有同樣的問題。

嘗試在代碼聲明集合視圖源:

CollectionViewSource StatusListViewSource = new CollectionViewSource(); 
StatusListViewSource.Source = SPL2StatusCollection; 

然後在XAML變化結合collectionviewsource:

ItemsSource="{Binding StatusListViewSource.View}" 

我從VB轉換,所以可能需要進行一些編輯。
這有幫助嗎?

+0

我仍然有同樣的錯誤。並且我確定它們是不同的實例,因爲當我加載它們時,它們從數據庫中獲取了正確的數據(不同),但是當切換選項卡時,它們複製數據(並檢查問題不在負載上,但在選項卡上更改) – andrea 2013-03-15 17:38:56

+0

對不起,我不知道從哪裏去。我通常開始逐步瞭解每一個過程。你能檢查底層綁定中發生了什麼嗎?也許這是一個用戶界面問題,其中viewmodel中的數據沒問題,但用戶界面錯誤。你在實現INotifyPropertyChanged嗎? – 2013-03-15 18:16:00

1

我重新創建了您的問題。但我找不到任何問題。請看下面的代碼,你可能會遇到困境。這是我的解決方案。

MyTab視圖模型

public class MyTab : ViewModelBase 
{ 
    #region Declarations 

    private ObservableCollection<string> statusList; 
    private string selectedStatus; 

    #endregion 

    #region Properties 

    /// <summary> 
    /// Gets or sets the header. 
    /// </summary> 
    /// <value>The header.</value> 
    public string Header { get; set; } 

    /// <summary> 
    /// Gets or sets the content. 
    /// </summary> 
    /// <value>The content.</value> 
    public string Content { get; set; } 

    /// <summary> 
    /// Gets or sets the status list. 
    /// </summary> 
    /// <value>The status list.</value> 
    public ObservableCollection<string> StatusList 
    { 
     get 
     { 
      return statusList; 
     } 
     set 
     { 
      statusList = value; 
      NotifyPropertyChanged("StatusList"); 
     } 
    } 

    /// <summary> 
    /// Gets or sets the selected status. 
    /// </summary> 
    /// <value>The selected status.</value> 
    public string SelectedStatus 
    { 
     get 
     { 
      return selectedStatus; 
     } 
     set 
     { 
      selectedStatus = value; 
      NotifyPropertyChanged("SelectedStatus"); 
     } 
    } 

    #endregion 
} 

MainViewModel視圖模型

public class MainViewModel : ViewModelBase 
{ 
    #region Declarations 

    private ObservableCollection<MyTab> tabs; 
    private MyTab selectedTab; 

    #endregion 

    #region Properties 

    /// <summary> 
    /// Gets or sets the tabs. 
    /// </summary> 
    /// <value>The tabs.</value> 
    public ObservableCollection<MyTab> Tabs 
    { 
     get 
     { 
      return tabs; 
     } 
     set 
     { 
      tabs = value; 
      NotifyPropertyChanged("Tabs"); 
     } 
    } 

    /// <summary> 
    /// Gets or sets the selected tab. 
    /// </summary> 
    /// <value>The selected tab.</value> 
    public MyTab SelectedTab 
    { 
     get 
     { 
      return selectedTab; 
     } 
     set 
     { 
      selectedTab = value; 
      NotifyPropertyChanged("SelectedTab"); 
     } 
    } 

    #endregion 

    #region Constructors 

    /// <summary> 
    /// Initializes a new instance of the <see cref="MainViewModel"/> class. 
    /// </summary> 
    public MainViewModel() 
    { 
     this.Tabs = new ObservableCollection<MyTab>(); 

     MyTab tab1 = new MyTab(); 
     tab1.Header = "tab1"; 
     tab1.Content = "Tab 1 content"; 
     ObservableCollection<string> tab1StatusList = new ObservableCollection<string>(); 
     tab1StatusList.Add("tab1 item1"); 
     tab1StatusList.Add("tab1 item2"); 
     tab1StatusList.Add("tab1 item3"); 
     tab1.StatusList = tab1StatusList; 
     tab1.SelectedStatus = tab1StatusList.First(); 
     this.Tabs.Add(tab1); 

     MyTab tab2 = new MyTab(); 
     tab2.Header = "tab2"; 
     tab2.Content = "Tab 2 content"; 
     ObservableCollection<string> tab2StatusList = new ObservableCollection<string>(); 
     tab2StatusList.Add("tab2 item1"); 
     tab2StatusList.Add("tab2 item2"); 
     tab2StatusList.Add("tab2 item3"); 
     tab2.StatusList = tab2StatusList; 
     tab2.SelectedStatus = tab2StatusList.First(); 
     this.Tabs.Add(tab2); 

     this.SelectedTab = tab1; 
    } 

    #endregion 
} 

最後,這是我XAML

<Window x:Class="ComboboxSelectedItem.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:viewModel="clr-namespace:ComboboxSelectedItem.ViewModels" 
    Title="MainWindow" Height="350" Width="525"> 
<Grid Name="mainGrid"> 

    <Grid.DataContext> 
     <viewModel:MainViewModel /> 
    </Grid.DataContext> 

    <TabControl 
     ItemsSource="{Binding Tabs, Mode=TwoWay}" 
     SelectedItem="{Binding SelectedTab}"> 

     <TabControl.ItemTemplate> 
      <DataTemplate> 
       <StackPanel Orientation="Horizontal"> 
        <TextBlock Text="{Binding Header}" Margin="0 0 20 0"/> 
       </StackPanel> 
      </DataTemplate> 
     </TabControl.ItemTemplate> 

     <!--Content section--> 
     <TabControl.ContentTemplate> 
      <DataTemplate> 
       <Grid> 
        <StackPanel Orientation="Vertical"> 
         <TextBlock 
          Text="{Binding Content}" /> 
         <ComboBox 
          ItemsSource="{Binding StatusList}" 
          SelectedItem="{Binding SelectedStatus}" /> 
        </StackPanel> 

       </Grid> 
      </DataTemplate> 
     </TabControl.ContentTemplate> 

    </TabControl> 
</Grid> 
</Window> 
+0

以及我發現了一個區別,我將它添加到我的問題中(重新編輯) – andrea 2013-03-18 14:14:49

+0

我在一個更簡單的應用程序中重現了錯誤(因此上傳一些代碼更容易)。 http://stackoverflow.com/questions/15531920/wpf-combobox-selection-change-after-switching-tabs如果您想要查看它,請提前致謝 – andrea 2013-03-20 18:37:33