MVVM WPF 从另一个 TabItem 的内容添加 TabItem
MVVM WPF Adding TabItem From Another TabItem's Content
您好,抱歉这么久了 post.I 希望没有人问过同样的问题。如果是这样,我请求你的借口。
我在使用 MVVM 方法从另一个 TabItem
的内容动态添加 TabItem
时遇到问题, 是 UserControl
。
MainWindow
绑定了一个名为 TabsMainViewModel
:
的视图模型 class
<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
的习俗 class 叫做 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
Class,我有:
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
属性 中,我设置了 UserControl
出现在 TabItem
的内容中。我的问题是:我怎样才能在这个 CustomerSearch
用户控件中放置一个按钮,并且那个按钮可以绑定像 ICommand
或 DelegateCommand
(例如在它的 CustomerSearchViewModel
中)这样的东西在 TabsMainViewModel
?
中执行 AddItem
函数
如果需要我可以 post 和 ObservableObject
和 DelegateCommand
classes
和 ITabContent
界面。
提前致谢
我已经解决了我的问题。我会 post 解决方案,仔细检查,如果有人有同样的问题。所以解决方案是:
添加一个 class,即 CustomerSearch
的名为 CustomerSearchViewModel
的视图模型。在此 class 中添加一个委托函数,以及一个在 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); });
}
}
}
}
在我创建 UserControl 实例的主视图模型 TabsMainViewModel
中,我注册了事件:
public ICommand CustomerSearch
{
get
{
CustomerSearch f = new CustomerSearch() { UniqueTabName = "NewTab1", Title = "Customer Search" };
CustomerSearchViewModel.AddNewCustomerTab += AddItem;
return new DelegateCommand(delegate { this.AddItem(f); });
}
}
我不知道这是否是正确的方法,但它对我有用。如果有人有最好的解决方案,请不要犹豫分享。
此致,
朱利安
您好,抱歉这么久了 post.I 希望没有人问过同样的问题。如果是这样,我请求你的借口。
我在使用 MVVM 方法从另一个 TabItem
的内容动态添加 TabItem
时遇到问题, 是 UserControl
。
MainWindow
绑定了一个名为 TabsMainViewModel
:
<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
的习俗 class 叫做 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
Class,我有:
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
属性 中,我设置了 UserControl
出现在 TabItem
的内容中。我的问题是:我怎样才能在这个 CustomerSearch
用户控件中放置一个按钮,并且那个按钮可以绑定像 ICommand
或 DelegateCommand
(例如在它的 CustomerSearchViewModel
中)这样的东西在 TabsMainViewModel
?
AddItem
函数
如果需要我可以 post 和 ObservableObject
和 DelegateCommand
classes
和 ITabContent
界面。
提前致谢
我已经解决了我的问题。我会 post 解决方案,仔细检查,如果有人有同样的问题。所以解决方案是:
添加一个 class,即 CustomerSearch
的名为 CustomerSearchViewModel
的视图模型。在此 class 中添加一个委托函数,以及一个在 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); });
}
}
}
}
在我创建 UserControl 实例的主视图模型 TabsMainViewModel
中,我注册了事件:
public ICommand CustomerSearch
{
get
{
CustomerSearch f = new CustomerSearch() { UniqueTabName = "NewTab1", Title = "Customer Search" };
CustomerSearchViewModel.AddNewCustomerTab += AddItem;
return new DelegateCommand(delegate { this.AddItem(f); });
}
}
我不知道这是否是正确的方法,但它对我有用。如果有人有最好的解决方案,请不要犹豫分享。
此致,
朱利安