2015-01-16 3 views
0

안녕하세요. 긴 게시물에 대해 유감입니다. 아무도 같은 질문을하지 않았 으면합니다. 그렇다면, 나는 당신의 변명을 요구합니다. TabItem을 동적으로 추가하는 데 문제가 있습니다. 다른 TabItem의 콘텐츠에서 마녀는 MVVM 방식을 사용하여 UserControl입니다. 내가 TabViewModel라는 사용자 정의 클래스 중 하나 ObservableCollection이있는 TabsMainViewModel에서MVVM 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" > 

: MainWindowTabsMainViewModel라는 바인더 제본 뷰 모델 클래스가 있습니다.

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 클래스, 나는이 다음 TabContent 속성에

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"); 
       } 
      } 
     } 
    } 
} 

나는 TabItem의 내용에 나타나는 UserControl을 설정합니다. 내 질문은 :이 CustomerSearch usercontrol 단추를 어떻게 넣을 수 ICommand 또는 DelegateCommand (예 : CustomerSearchViewModel)에서 AddItem 함수를 실행할 수있는 단추를 TabsMainViewModel 바인딩 할 수 있습니까?

필요한 경우 게시 할 수 있으며 ObservableObjectDelegateCommand 클래스 및 ITabContent 인터페이스를 게시 할 수 있습니다. 미리 감사드립니다.

+0

주세요, 지금은'폐기()'메소드를 구현하지 않습니다. 이 메서드는 비 결정적 방법으로 가비지 수집기에서 호출 할 수 있습니다. 즉, 언제, 얼마나 자주 스레드를 호출하는지 알 수 없습니다. – dymanoid

+0

팁 주셔서 감사. 나는 그것을 염두에 두겠다. 내가 물어 본 질문에 대한 제안 사항이 있습니까? :) –

답변

0

나는 내 문제를 친절하게 해결했습니다. 나는 해결책을 게시 할 것이다. 이중 점검을 위해, 그리고 누군가가 똑같은 문제를 안고 있다면. 해결책은 다음과 같습니다.

CustomerSearchViewModel이라는 의보기 모델 인 클래스를 추가하십시오. 이 클래스에서는 대리자 기능 및 TabsMainViewModel에 등록 된 이벤트 추가 :

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

     } 
:

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); }); 
      } 

     } 

    } 
} 

내가 UserControl을의 인스턴스를 생성 메인 뷰 모델 TabsMainViewModel에서를, 나는 이벤트를 등록

이것이 올바른 접근 방법인지는 모르겠지만 저에게는 효과적입니다. 누군가 최상의 솔루션을 보유하고 있다면 주저하지 말고 공유하십시오. 당신은`TabViewModel` 클래스를했던 것처럼

최고 감사합니다,

줄리안