2015-01-16 139 views
0

您好,对于长篇帖子感到抱歉。我希望没有人问过同样的问题。如果是这样,我请你找借口。 我使用MVVM方法动态添加TabItem时遇到问题,从另一个TabItem的内容中,女士是UserControl。 的MainWindow具有绑定一个视图模型类叫做TabsMainViewModelMVVM WPF从另一个TabItem的内容中添加TabItem

<Window x:Name="Main" x:Class="Interface_test.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:vm="clr-namespace:Interface_test" 
     xmlns:uc="clr-namespace:Interface_test.Customers" 
     Title="MainWindow" Height="850" Width="825" WindowStartupLocation="CenterScreen" WindowState="Maximized"> 
    <Window.DataContext> 
     <vm:TabsMainViewModel /> 
    </Window.DataContext> 
    <Window.Resources> 
    <DataTemplate x:Key="TabItemTemplate"> 
     <DockPanel> 
      <Button Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}" 
        Background="Transparent" 
        Name="btnDelete" 
        DockPanel.Dock="Right" 
        Margin="5,0,0,0" 
        Padding="0" 
        Command="{Binding RemoveItemCommand}"> 
       <Image Height="11" Width="11" Source="Images/closeButton.png"/> 
      </Button> 
      <TextBlock Text="{Binding Header}" /> 
     </DockPanel> 
    </DataTemplate> 
    <DataTemplate x:Key="TabItemContent" > 
     <UserControl Content="{Binding TabContent}"/> 
    </DataTemplate> 
    <Style TargetType="TabItem"> 
     <Setter Property="IsSelected" 
       Value="{Binding IsSelected, Mode=TwoWay}"/> 
    </Style> 
</Window.Resources> 
<TabControl ItemTemplate="{StaticResource TabItemTemplate}" 
       ContentTemplate="{StaticResource TabItemContent}" 
       ItemsSource="{Binding Tabs}" 
       HorizontalAlignment="Stretch" 
       VerticalAlignment="Stretch" 
       VerticalContentAlignment="Stretch" 
       HorizontalContentAlignment="Stretch" 
       Name="tcMDI" 
       Visibility="Visible" 
       ScrollViewer.HorizontalScrollBarVisibility="Auto" 
       ScrollViewer.VerticalScrollBarVisibility="Auto" > 

TabsMainViewModel我有一个ObservableCollection称为TabViewModel的定制类。

public class TabsMainViewModel 
    { 
     int tabCounter; 
     private Dictionary<string, string> _openedTabs = new Dictionary<string, string>(); 
     public TabsMainViewModel() 
     { 
      this.Tabs=new ObservableCollection<TabViewModel>(); 
      //this.AddItem(null); 
     } 
     public ObservableCollection<TabViewModel> Tabs 
     { 
      get; 
      private set; 
     } 
     public ICommand CustomerSearch 
     { 
      get 
      { 
       CustomerSearch f = new CustomerSearch() { UniqueTabName = "NewTab1", Title = "Customer Search" }; 
       return new DelegateCommand(delegate { this.AddItem(f); }); 
      } 

     } 
     public ICommand Customer 
     { 
      get 
      { 
       Customer f = new Customer() { UniqueTabName = "NewTab2", Title = "Customer" }; 
       return new DelegateCommand(delegate { this.AddItem(f); }); 
      } 

     } 
     public ICommand EmployerSearch 
     { 
      get 
      { 
       CustomerSearch f = new CustomerSearch() { UniqueTabName = "NewTab3", Title = "Employer Search" }; 
       return new DelegateCommand(delegate { this.AddItem(f); }); 
      } 
     } 
     public ICommand Employer 
     { 
      get 
      { 
       Customer f = new Customer() { UniqueTabName = "NewTab4", Title = "Employer" }; 
       return new DelegateCommand(delegate { this.AddItem(f); }); 
      } 

     } 
     public void AddItem(ITabContent userControl) 
     { 

      if (_openedTabs.ContainsKey(userControl.UniqueTabName)) 
      { 
       foreach (TabViewModel tvm in Tabs) 
       { 
        if (userControl.UniqueTabName == tvm.TabContent.UniqueTabName) 
        { 
         tvm.IsSelected = true; 
         break; 
        } 
       } 
      } 
      else 
      { 
       TabViewModel tabItem = new TabViewModel(this) { TabContent = userControl }; 
       tabItem.TabContent.Title += " " + tabCounter; 
       tabItem.IsSelected = true; 
       Tabs.Add(tabItem); 
       _openedTabs.Add(tabItem.TabContent.UniqueTabName, tabItem.TabContent.Title); 
       tabCounter++; 
      } 

     } 
     public void RemoveItem(TabViewModel tabItem) 
     { 
      this.Tabs.Remove(tabItem); 
      _openedTabs.Remove(tabItem.TabContent.UniqueTabName); 
      tabItem.Dispose(); 

     } 
    } 
} 

TabViewModel类,我有:

public class TabViewModel:ObservableObject,IDisposable 
    { 
     private bool _isSelected; 
     private ITabContent _tabContent; 
     private readonly TabsMainViewModel tabsMainViewModel; 

     public TabViewModel(TabsMainViewModel tabsMainViewModel) 
     { 
      this.tabsMainViewModel = tabsMainViewModel; 
      this.tabsMainViewModel.Tabs.CollectionChanged += this.Tabs_CollectionChanged; 


      this.RemoveItemCommand = new DelegateCommand(
       delegate 
       { 
        this.tabsMainViewModel.RemoveItem(this); 
       }, 
       delegate 
       { 
        return this.tabsMainViewModel.Tabs.Count > 1; 
       } 
       ); 
     } 
     public void Dispose() 
     { 
      this.tabsMainViewModel.Tabs.CollectionChanged -= this.Tabs_CollectionChanged; 
     } 
     private void Tabs_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) 
     { 
      this.RemoveItemCommand.RaiseCanExecuteChanged(); 
     } 

     public DelegateCommand RemoveItemCommand { get; set; } 

     public ITabContent TabContent 
     { 
      get { return _tabContent;} 
      set 
      { 
       _tabContent = value; 
       _tabContent.Parent = this; 
       Header = value.Title; 
      } 
     } 
     public String Header 
     { 
      get; 
      private set; 
     } 
     public bool IsSelected 
     { 
      get { return this._isSelected; } 
      set 
      { 
       if (this._isSelected != value) 
       { 
        this._isSelected = value; 
        RaisePropertyChangedEvent("IsSelected"); 
       } 
      } 
     } 
    } 
} 

TabContent属性我设置出现在TabItem的内容UserControl。我的问题是:如何在这个CustomerSearch用户控件中放置一个按钮,并且该按钮绑定类似ICommandDelegateCommand(例如在其CustomerSearchViewModel中)可以执行TabsMainViewModel中的AddItem函数?

如果需要,我可以发帖和ObservableObjectDelegateCommand类 和ITabContent接口。 在此先感谢

+0

请,从来没有实施'的Dispose()'方法像你这样做是为了'TabViewModel'类。垃圾回收器可以以非确定的方式调用此方法,这意味着 - 您无法知道何时,多少次以及由哪个线程调用它。 – dymanoid

+0

感谢您的提示。我会记住这一点。关于我问过的问题的任何建议? :) –

回答

0

我一直在解决我的问题。我会发布解决方案,进行双重检查,如果有人遇到同样的问题。所以解决方案是:

添加一个类CustomerSearch的视图模型CustomerSearchViewModel。在这个类中添加一个委托功能,那就是在TabsMainViewModel注册的事件:

namespace Interface_test.Customers 
{ 
    public delegate void OpenNewTab(ITabContent uc); 
    class CustomerSearchViewModel 
    { 
     public static event OpenNewTab AddNewCustomerTab = delegate { }; 
     public CustomerSearchViewModel() 
     { 

     } 
     public ICommand ShowCustomer 
     { 
      get 
      { 
       Customer f = new Customer() { UniqueTabName = "NewTab12", Title = "Customer from search" }; 
       return new DelegateCommand(delegate {AddNewCustomerTab(f); }); 
      } 

     } 

    } 
} 

在主视图模型TabsMainViewModel,我创建用户控件的实例,我注册事件:

public ICommand CustomerSearch 
     { 
      get 
      { 
       CustomerSearch f = new CustomerSearch() { UniqueTabName = "NewTab1", Title = "Customer Search" }; 
       CustomerSearchViewModel.AddNewCustomerTab += AddItem; 
       return new DelegateCommand(delegate { this.AddItem(f); }); 
      } 

     } 

我不知道这是否正确,但它对我有效。如果有人有最佳解决方案,请不要犹豫分享。

最好的问候,

朱利安