TabItem
<Style x:Key="SubStudioTabItem" TargetType="{x:Type TabItem}">
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid Height="20"
Background="{TemplateBinding Background}"
SnapsToDevicePixels="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<ContentPresenter Grid.Column="0"
Margin="10,0,10,0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
ContentSource="Header" />
<Button Grid.Column="1"
x:Name="CloseButton"
Width="15"
Height="15"
HorizontalAlignment="Center"
VerticalAlignment="Center"
DockPanel.Dock="Right"
AttachedCommand:CommandBehavior.Event="Click"
AttachedCommand:CommandBehavior.Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}},
Path=DataContext.CloseWorkspaceCommand}">
...
现在我想让Button
的可选TabItem
的可见性可用于DataTemplate
<DataTemplate x:Key="WorkspaceTemplate">
<TabControl x:Name="tabControl"
IsSynchronizedWithCurrentItem="true"
Style="{StaticResource StudioTabControl}"
ItemsSource="{Binding Workspaces}"
SelectedIndex="{Binding SelectedIndex, NotifyOnSourceUpdated=True, Mode=TwoWay}">
<TabControl.ItemContainerStyle>
<Style TargetType="TabItem"
BasedOn="{StaticResource SubStudioTabItem}">
<Setter Property="??Button.Visibility??" Value="{Binding Path=Display, Converter={StaticResource BooleanToVisibiltyConverter}}"/>
</Style>
</TabControl.ItemContainerStyle>
</TabControl>
</DataTemplate>
如何设置TabItem
上DataTemplate
上按钮的可见性状态?
感谢您的时间。
答案 0 :(得分:1)
在这种情况下,我会创建附加属性,例如Visibility
的类型,并在TemplateBinding
中生成Style
,类似这样:
<ControlTemplate TargetType="{x:Type TabItem}">
...
<Button Grid.Column="1"
x:Name="CloseButton"
Visibility="{TemplateBinding local:MyClass.ButtonVisibility}"
...
</Button>
TabItem
中的<ItemContainerStyle>
会写这个(或其他地方):
<Style TargetType="TabItem" BasedOn="{StaticResource SubStudioTabItem}">
<Setter Property="local:MyClass.ButtonVisibility" Value="{Binding Path=Display, Converter={StaticResource BooleanToVisibiltyConverter}}"/>
</Style>
<强> Edit:
强>
我创建了一个实现此方法的项目。在该项目中尝试遵循 MVVM 模式。项目结构:
按顺序开始,在文件夹AttachedProperties
中有一个附加属性,它负责Button
的外观。
ButtonVisibility.cs
的代码:
using System;
using System.Windows;
public class ButtonVisibilityPro : DependencyObject
{
public static readonly DependencyProperty ButtonVisibilityProperty;
public static void SetButtonVisibility(DependencyObject DepObject, Visibility value)
{
DepObject.SetValue(ButtonVisibilityProperty, value);
}
public static Visibility GetButtonVisibility(DependencyObject DepObject)
{
return (Visibility)DepObject.GetValue(ButtonVisibilityProperty);
}
static ButtonVisibilityPro()
{
PropertyMetadata MyPropertyMetadata = new PropertyMetadata(Visibility.Collapsed);
ButtonVisibilityProperty = DependencyProperty.RegisterAttached("ButtonVisibility",
typeof(Visibility),
typeof(ButtonVisibilityPro),
MyPropertyMetadata);
}
}
数据模型为ButtonModel
,其中布尔属性为ButtonDisplay
。此类继承自实现 INotifyPropertyChanged 的ViewModelBase
。
<强> ButtonModel.cs
强>
using System;
using ButtonVisibilityHelp.ViewModels;
namespace ButtonVisibilityHelp.Models
{
public class ButtonModel : ViewModelBase
{
private bool _buttonDisplay = false;
public bool ButtonDisplay
{
get
{
return _buttonDisplay;
}
set
{
_buttonDisplay = value;
NotifyPropertyChanged("ButtonDisplay");
}
}
}
}
ViewModelBase.cs
using System;
using System.ComponentModel;
namespace ButtonVisibilityHelp.ViewModels
{
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
<强> ButtonViewModel.cs
强>
using System;
using System.Windows.Input;
using System.Windows;
using ButtonVisibilityHelp.Models;
using ButtonVisibilityHelp.Workers;
namespace ButtonVisibilityHelp.ViewModels
{
public class ButtonViewModel : ViewModelBase
{
private ButtonModel _buttonModel;
private ICommand _hideButtonCommand = null;
private ICommand _showButtonCommand = null;
public ButtonModel ButtonModel
{
get
{
return _buttonModel;
}
set
{
_buttonModel = value;
NotifyPropertyChanged("ButtonModel");
}
}
public ICommand HideButtonCommand
{
get
{
if (_hideButtonCommand == null)
{
_hideButtonCommand = new RelayCommand(param => this.HideButton(), null);
}
return _hideButtonCommand;
}
}
public ICommand ShowButtonCommand
{
get
{
if (_showButtonCommand == null)
{
_showButtonCommand = new RelayCommand(param => this.ShowButton(), null);
}
return _showButtonCommand;
}
}
public ButtonViewModel()
{
ButtonModel = new ButtonModel();
}
private void HideButton()
{
ButtonModel.ButtonDisplay = false;
}
private void ShowButton()
{
ButtonModel.ButtonDisplay = true;
}
}
}
<强> RelayCommand.cs
强>
using System;
using System.Windows.Input;
namespace ButtonVisibilityHelp.Workers
{
public class RelayCommand : ICommand
{
private readonly Action<object> _execute;
private readonly Predicate<object> _canExecute;
public RelayCommand(Action<object> execute) : this(execute, null)
{
}
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
{
throw new ArgumentNullException("execute");
}
_execute = execute;
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute(parameter);
}
public event EventHandler CanExecuteChanged
{
add
{
CommandManager.RequerySuggested += value;
}
remove
{
CommandManager.RequerySuggested -= value;
}
}
public void Execute(object parameter)
{
_execute(parameter);
}
}
}
下面是一段XAML代码,格式为TabItem
:
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid Background="{TemplateBinding Background}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<Border Grid.Column="0" SnapsToDevicePixels="True" Name="Border" Margin="0,0,2,0" Padding="2" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="0">
<ContentPresenter Name="ContentSite"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="5,5,5,5"
VerticalAlignment="Center"
RecognizesAccessKey="True"
ContentSource="Header" />
</Border>
<!-- Here TemplateBinding for Visibility -->
<Button Name="CloseButton" Style="{StaticResource CloseButton}"
Visibility="{TemplateBinding AttachedProperties:ButtonVisibilityPro.ButtonVisibility}"
Grid.Column="1" Width="14" Height="14" HorizontalAlignment="Center" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="TabStripPlacement" Value="Bottom">
<Setter TargetName="Border" Property="CornerRadius" Value="0,0,0,0" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
MainWindow
的XAML:
<Window x:Class="ButtonVisibilityHelp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ViewModels="clr-namespace:ButtonVisibilityHelp.ViewModels"
xmlns:AttachedProperties="clr-namespace:ButtonVisibilityHelp.AttachedProperties"
WindowStartupLocation="CenterScreen"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<ViewModels:ButtonViewModel x:Key="MyButtonViewModel" />
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</Window.Resources>
<Grid DataContext="{Binding Source={StaticResource MyButtonViewModel}}">
<TabControl>
<TabControl.ItemContainerStyle>
<Style TargetType="{x:Type TabItem}" BasedOn="{StaticResource {x:Type TabItem}}">
<Setter Property="AttachedProperties:ButtonVisibilityPro.ButtonVisibility" Value="{Binding Path=ButtonModel.ButtonDisplay, Converter={StaticResource BooleanToVisibilityConverter}}" />
</Style>
</TabControl.ItemContainerStyle>
<TabItem Header="Test1">
<StackPanel>
<TextBlock Text="{Binding ButtonModel.ButtonDisplay, StringFormat=ButtonDisplay: {0}, Mode=TwoWay}" HorizontalAlignment="Right" />
<Button Name="ShowInTest1" Command="{Binding ShowButtonCommand}" Width="100" Height="30" Content="Show me" HorizontalAlignment="Right" />
<Button Name="HideInTest1" Command="{Binding HideButtonCommand}" Width="100" Height="30" Content="Hide me" HorizontalAlignment="Right" />
</StackPanel>
</TabItem>
<TabItem Header="Test2">
<StackPanel>
<TextBlock Text="{Binding ButtonModel.ButtonDisplay, StringFormat=ButtonDisplay: {0}, Mode=TwoWay}" HorizontalAlignment="Right" />
<Button Name="ShowInTest2" Command="{Binding ShowButtonCommand}" Width="100" Height="30" Content="Show me" HorizontalAlignment="Right" />
<Button Name="HideInTest2" Command="{Binding HideButtonCommand}" Width="100" Height="30" Content="Hide me" HorizontalAlignment="Right" />
</StackPanel>
</TabItem>
</TabControl>
</Grid>
</Window>
Output
告诉我:
隐藏我:
完整的代码示例位于此link。
答案 1 :(得分:0)
在Tag
上设置TabItem
属性,如下所示:
<TabControl.ItemContainerStyle>
<Style TargetType="TabItem"
BasedOn="{StaticResource SubStudioTabItem}">
<Setter Property="Tag" Value="{Binding IsVisible, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"/>
</Style>
</TabControl.ItemContainerStyle>
然后在ControlTemplate
添加DataTrigger
以根据Tag属性设置CloseButton的Visibility
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding Tag}", Value="false">
<Setter Property="Visibility" TargetName="CloseButton" Value="Collapsed"/>
</DataTrigger>
</ControlTemplate.Triggers>