I'm trying to have my TabItem Collapsed or Hidden. I've tried many solutions and none have worked. The Tab Item still remains
If I may get some guidance please.
one solution I've Tried
<TabItem >
<TabItem.Header>
<StackPanel Visibility="Collapsed">
<TextBlock Text="Transactions" />
</StackPanel>
</TabItem.Header>
<panes:Transactions />
</TabItem>
private Visibility statementVisibility;
public Visibility StatementVisibility { get { return statementVisibility; } set { statementVisibility = value; OnPropertyChanged("StatementVisibillity"); } }
Changed "Collapsed" to StatementVisibility and still nothing.
UPDATE:
After poking around, I've found a link to the TabItems that I think may play a factor.
Generic.xaml
<ListBox Foreground="#FFF" Name="TabSelector" Grid.Row="2" ItemsSource="{Binding Path=Items, ElementName=Tabs}">
<ListBox.Background>
<SolidColorBrush Color="#333"/>
</ListBox.Background>
<ListBox.ItemTemplate>
<DataTemplate>
<Border BorderThickness="0 0 0 1" SnapsToDevicePixels="False" BorderBrush="#22000000">
<TextBlock FontSize="14" Height="30" VerticalAlignment="Center" Margin="0" Padding="6" Text="{Binding Header}"/>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Border Grid.Column="1" Grid.Row="2" Background="White" BorderThickness="0">
<ContentPresenter Name="PART_TabbedFormPresenter"
Content="{Binding TabbedForm, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type shell:ActionScreenControl}}}"
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type shell:ActionScreenControl}}}">
<ContentPresenter.Resources>
<Style TargetType="TabItem">
<Setter Property="Visibility" Value="Collapsed"/>
<Setter Property="BorderThickness" Value="0"/>
</Style>
</ContentPresenter.Resources>
</ContentPresenter>
</Border>
Loanview.xaml.cs
<shell:ActionScreenControl.TabbedForm>
<TabControl>
<TabItem......./>
<TabItem......./>
<TabItem >
<TabItem.Header>
<StackPanel Visibility="Collapsed">
<TextBlock Text="Transactions" />
</StackPanel>
</TabItem.Header>
<panes:Transactions />
</TabItem>
</TabControl>
</shell:ActionScreenControl.TabbedForm>
Try setting the Visibility property on the actual TabItem itself:
<TabControl>
<TabItem Visibility="Collapsed">
<TabItem.Header>
<StackPanel>
<TextBlock Text="Transactions" />
</StackPanel>
</TabItem.Header>
<panes:Transactions />
</TabItem>
</TabControl>
Ahhhh... you want to data bind. Then you'll need to use a BooleanToVisibilityConverter element and a bool property:
<TabItem Visibility="{Binding YourBoolProperty,
Converter={StaticResource BooleanToVisibilityConverter}">
<TabItem.Header>
<StackPanel>
<TextBlock Text="Transactions" />
</StackPanel>
</TabItem.Header>
<panes:Transactions />
</TabItem>
See the IValueConverter Interface page on MSDN to see how to use a converter.
This is from production code and it works
<TabItem Visibility="{Binding Path=MyGabeLib.CurUser.DisplayTSQL, Converter={StaticResource bvc}}">
<TabItem.Header>
<TextBlock Style="{StaticResource HeaderTextBlockStyle}">TSQL</TextBlock>
</TabItem.Header>
<ScrollViewer VerticalScrollBarVisibility="Visible">
<TextBox Text="{Binding Path=MyGabeLib.Search.CurrentTSQL, Mode=OneWay}" IsReadOnly="True"
TextWrapping="Wrap" FontFamily="Courier New"/>
</ScrollViewer>
</TabItem>
If you are returning Visibility then you would not need a converter
Try with a simple TextBlock - I suspect you have a datacontext problem
Related
I have a list box Bound to XML data correctly , but i have multiple Tree Views inside this listbox which you can select item for every one of them!
i want single item selecting from all of these tree views. which every one of those are inside an unique expander.
if you look at my xml data ,consider i have 2 groups inside xml , i can select item for both of those groups in listbox which now they are different treeviews in my ui , and i want single item selecting for all this listbox items.
<ListBox Background="Transparent" BorderThickness="0" SelectedValue="{Binding SelectedMenuValue,Mode=TwoWay}" ItemsSource="{Binding Path=Items,Source={StaticResource XmlSourceMenu}}">
<ListBox.Resources>
<DataTemplate DataType="{x:Type revoxml:Group}">
<Expander Header="{Binding Title}">
<TreeView ItemsSource="{Binding Menus}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding}">
<StackPanel Orientation="Horizontal" Margin="10 0">
<fa:ImageAwesome Height="30" Width="30" VerticalAlignment="Center" Margin="5" Icon="{Binding Icon}" />
<TextBlock Text="{Binding Title}" Height="30" VerticalAlignment="Center" Margin="5"/>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Expander>
</DataTemplate>
<DataTemplate DataType="{x:Type revoxml:SubMenu}">
<StackPanel Orientation="Horizontal" Margin="10 0">
<fa:ImageAwesome Height="30" Width="30" VerticalAlignment="Center" Margin="5" Icon="{Binding Icon}" />
<TextBlock Text="{Binding Title}" Height="30" VerticalAlignment="Center" Margin="5"/>
</StackPanel>
</DataTemplate>
</ListBox.Resources>
</ListBox>
for easier understanding data for this listbox comming from xml file like this :
<MainMenu>
<Group Title="title">
<SubMenu Icon="Inbox" Title="inbox" Tag="38"/>
<SubMenu Icon="CommentingOutline" Title="New Message" Tag="37"/>
<SubMenu Icon="Tachometer" Title="Archive" Tag="39"/>
<Menu Icon="CartArrowDown" Title="purchases" >
<SubMenu Icon="CartArrowDown" Title="new" Tag="26"/>
<SubMenu Icon="CartPlus" Title="list" Tag="28"/>
</Menu>
</Group>
<SubMenu Icon="InfoCircle" Title="info" Tag="6000" />
<SubMenu Icon="Close" Title="close" Tag="0"/>
</MainMenu>
this should solve it ! but you need to implement your own selected item, or you could change groupboxes to expander and items control to tree view to match your code
<Style TargetType="StackPanel" x:Key="HoverStackPanelStyle">
<Setter Property="Background" Value="Transparent"></Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
<ScrollViewer>
<HeaderedItemsControl Background="Transparent" ItemsSource="{Binding Path=Items,Source={StaticResource XmlSourceMenu}}">
<ItemsControl.Resources>
<DataTemplate DataType="{x:Type revoxml:SubMenu}">
<StackPanel Orientation="Horizontal" Margin="10 0" Style="{StaticResource HoverStackPanelStyle}">
<fa:ImageAwesome Height="30" Width="30" VerticalAlignment="Center" Margin="5" Icon="{Binding Icon}" />
<TextBlock Text="{Binding Title}" FontFamily="{StaticResource nazanin}" Height="30" VerticalAlignment="Center" Margin="5"/>
</StackPanel>
</DataTemplate>
<HierarchicalDataTemplate DataType="{x:Type revoxml:Menu}" ItemsSource="{Binding Menus}">
<GroupBox Header="{Binding Title}" Margin="0 5">
<ItemsControl ItemsSource="{Binding Menus}">
<ItemsControl.Resources>
<DataTemplate DataType="{x:Type revoxml:SubMenu}">
<StackPanel Name="StackPanel" Orientation="Horizontal" Margin="10 0" Style="{StaticResource HoverStackPanelStyle}">
<fa:ImageAwesome Height="30" Width="30" VerticalAlignment="Center" Margin="5" Icon="{Binding Icon}" />
<TextBlock Text="{Binding Title}" FontFamily="{StaticResource nazanin}" Height="30" VerticalAlignment="Center" Margin="5"/>
</StackPanel>
</DataTemplate>
</ItemsControl.Resources>
</ItemsControl>
</GroupBox>
</HierarchicalDataTemplate>
</ItemsControl.Resources>
</HeaderedItemsControl>
</ScrollViewer>
I have to change Background color of an ItemTemplate of a ListBox, depending the value of a boolean.
Here is my ListBox :
<ListBox Name="itemListBox"
ScrollViewer.VerticalScrollBarVisibility="Visible"
SelectionChanged="itemListBox_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<StackPanel Width="200">
<TextBlock FontSize="10"
FontWeight="Bold"
VerticalAlignment="Center"
Text="{Binding Path=Value.DocID}" />
<TextBlock FontSize="10"
VerticalAlignment="Center"
TextWrapping="Wrap"
Text="{Binding Path=Value.Serial}"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
If the user delete an Item, I want to show him in grey backrgound.
Precision : The ListBox is binded to a Dictionnary, that contains a boolean value "IsDeleted".
Sorry for the poor English.
Thank you
You could use an ItemContainerStyle with a DataTrigger:
<ListBox Name="itemListBox" ScrollViewer.VerticalScrollBarVisibility="Visible" SelectionChanged="itemListBox_SelectionChanged">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Style.Triggers>
<DataTrigger Binding="{Binding Value.IsDeleted}" Value="True">
<Setter Property="Background" Value="Gray" />
</DataTrigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<StackPanel Width="200">
<TextBlock FontSize="10" FontWeight="Bold" VerticalAlignment="Center" Text="{Binding Path=Value.DocID}" />
<TextBlock FontSize="10" VerticalAlignment="Center" TextWrapping="Wrap" Text="{Binding Path=Value.Serial}"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Make sure that the class with the IsDeleted property implements the INotifyPropertyChanged interface correctly if you intend to set the property dynamically and want the background to get updated accordingly.
Sample code:
<TabControl>
<TabItem>
<TabItem.Header>
<StackPanel Orientation="Horizontal" Margin="5">
<Image Source="/WpfTutorialSamples;component/Images/bullet_blue.png" />
<TextBlock Text="Blue" Foreground="Blue" />
</StackPanel>
</TabItem.Header>
<Label Content="Content goes here..." />
</TabItem>
<TabItem>
<TabItem.Header>
<StackPanel Orientation="Horizontal" Margin="5">
<TextBlock Text="Red" Foreground="Red" />
</StackPanel>
</TabItem.Header>
</TabItem>
<TabItem>
<TabItem.Header>
<StackPanel Orientation="Horizontal" Margin="5">
<Rectangle Fill="Red" width="20" height="16" />
</StackPanel>
</TabItem.Header>
</TabItem>
</TabControl>
As you can see, the TabItem Header is Always a stackpanel with different content:
<TabItem.Header>
<StackPanel Orientation="Horizontal" Margin="5">
</StackPanel>
</TabItem.Header>
How can you put this in a template so that I don't have duplicate stackpanel code?
Trying to do it like this:
<TabControl>
<TabControl.Resources>
<Style TargetType="TabItem">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="5">
<ContentPresenter Content="{TemplateBinding ContentControl.Content}"
ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}"
ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}">
</ContentPresenter>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</TabControl.Resources>
<TabItem>
<TabItem.Header>
<!-- ??? -->
<TextBlock Text="X" />
<TextBlock Text="Y" />
</TabItem.Header>
</TabControl>
results in:
"The property 'Header' is set more than once."
"The object 'Object' already has a child and cannot add 'TextBlock'. 'Object' can accept only one child."
The only thing the tree headers really have common is the Margin="5". In second and third tab the stackpanel is irrelavant, because it has only one child. You can achive it either by using HeaderTemplate or ItemContainerStyle:
<TabControl>
<TabControl.ItemContainerStyle>
<Style TargetType="TabItem">
<Setter Property="Padding" Value="5" />
</Style>
</TabControl.ItemContainerStyle>
<TabItem>
<TabItem.Header>
<StackPanel Orientation="Horizontal">
<Image Source="/WpfTutorialSamples;component/Images/bullet_blue.png" />
<TextBlock Text="Blue" Foreground="Blue" />
</StackPanel>
</TabItem.Header>
<Label Content="Content goes here..." />
</TabItem>
<TabItem>
<TabItem.Header>
<TextBlock Text="Red" Foreground="Red" />
</TabItem.Header>
</TabItem>
<TabItem>
<TabItem.Header>
<Rectangle Fill="Red" Width="20" Height="16" />
</TabItem.Header>
</TabItem>
</TabControl>
now you don't repeat anything.
You could also extract the properties of stackpanel to style to avoid repeating them:
<TabItem.Header>
<StackPanel Style="{StaticResource TabHeaderPanel}">
<Image Source="/WpfTutorialSamples;component/Images/bullet_blue.png" />
<TextBlock Text="Blue" Foreground="Blue" />
</StackPanel>
</TabItem.Header>
<TabItem.Header>
<StackPanel Style="{StaticResource TabHeaderPanel}">
<TextBlock Text="Red" Foreground="Red" />
</StackPanel>
</TabItem.Header>
<TabItem.Header>
<StackPanel Style="{StaticResource TabHeaderPanel}">
<Rectangle Fill="Red" width="20" height="16" />
</StackPanel>
</TabItem.Header>
If you want even more code reuse, you should consider MVVM-like approach:
<TabControl ItemsSource="{Binding Tabs}">
<TabControl.ItemContainerStyle>
<Style TargetType="TabItem">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate DataType="local:TabViewModel">
<StackPanel Orientation="Horizontal" Margin="5">
<Image x:Name="Icon" Source="{Binding Icon, Converter={StaticResource UriToBitmapSourceConverter}}" />
<Rectangle x:Name="ColorRect" Height="16" Width="16" Fill="{Binding Color}" Visibility="Collapsed" />
<TextBlock Text="{Binding Title}" Foreground="{Binding Color}"/>
</StackPanel>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Icon}" Value="{x:Null}">
<Setter TargetName="Icon" Property="Visibility" Value="Collapsed" />
<Setter TargetName="ColorRect" Property="Visibility" Value="Visible" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</TabControl.ItemContainerStyle>
</TabControl>
if you can't use single DataTemplate for all headers, you can use HeaderTemplateSelector
I think HeaderTemplate will only be used if you are binding the Tab collection and generating them dynamically. This would work if you set your objects in a ViewModel (Header property is a collection of items that with implicit DataTemplates, could generate TextBlocks or Rectangles depending on their types).
Otherwise, you would either need to give your StackPanels common styling to make them all identical and save repetition, or set the first element of the TabItem.Header content to a custom control that derives from StackPanel.
I would choose the Style route myself, unless there is a really pressing need to remove even the StackPanel line from your XAML.
I know normally we can use this codes to bind Selected Tab Header Text and show selected tab:
<TabControl Name="MyTabControl">
<TabItem Header="Tab1"/>
<TabItem Header="Tab2" />
</TabControl>
<Lable Content="{Binding ElementName=MyTabControl, Path=SelectedItem.Header}"/>
But how can i bind when i have this codes:
<TabControl Name="MyTabControl">
<TabItem>
<TabItem.Header>
<StackPanel Orientation="Horizontal">
<Image Source="/Images/a.png" />
<TextBlock Text="Tab1" />
</StackPanel>
</TabItem.Header>
</TabItem>
<TabItem>
<TabItem.Header>
<StackPanel Orientation="Horizontal">
<Image Source="/Images/b.png" />
<TextBlock Text="Tab2" />
</StackPanel>
</TabItem.Header>
</TabItem>
<Lable Content="{Binding ??????????? "/>
Instead of assigning direct content to header you can make use of HeaderTemplate.
Refer below code.
<TabControl Name="MyTabControl">
<TabItem Header="Tab1">
<TabItem.HeaderTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="/Images/a.png" />
<TextBlock Text="{Binding}"/>
</StackPanel>
</DataTemplate>
</TabItem.HeaderTemplate>
</TabItem>
<TabItem Header="Tab2">
<TabItem.HeaderTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="/Images/b.png" />
<TextBlock Text="{Binding}"/>
</StackPanel>
</DataTemplate>
</TabItem.HeaderTemplate>
</TabItem>
</TabControl>
<Label Content="{Binding ElementName=MyTabControl, Path=SelectedItem.Header}"/>
i have one problem with tooltip.
I want to add templated tooltip to button with some information inside.
Here the button with tooltip, which datacontext bounded to some viewmodel:
<fluent:Button DataContext="{Binding NewConnections, Source={StaticResource Locator}}" Command="{Binding AddCloudStorageAccount}" Header="Add Account">
<fluent:Button.LargeIcon>
<Image Source="pack://application:,,,/Icons;component/UI/v1/add_account.png" Width="48"/>
</fluent:Button.LargeIcon>
<fluent:Button.ToolTip>
<ToolTip DataContext="{Binding UserInput.AddAccountsButtonInfo, Source={StaticResource Locator}}" Style="{StaticResource ButtonTooltip}"></ToolTip>
</fluent:Button.ToolTip>
</fluent:Button>
Style:
<Style TargetType="ToolTip" x:Key="ButtonTooltip">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Border Background="LightYellow" BorderThickness="0.5" BorderBrush="Maroon">
<StackPanel Orientation="Vertical" Margin="3">
<TextBlock x:Name="_txtText" Text="{Binding Title}"></TextBlock>
<TextBlock x:Name="_txtDescription" Margin="0 10 0 0" Text="{Binding Description}"></TextBlock>
<TextBlock x:Name="_txtHotKeyDescription" Margin="0 10 0 0" Text="{Binding HotKeyDescription}"></TextBlock>
</StackPanel>
</Border>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
I set some breakpoints to see if viewmodel is accessed. And it's ok. But properties like Title not accessed at all and i see only empty rectangle without any text
Do someone have some ideas?
Just resolved it(set datacontext in border). Maybe someone will be interested in:
<Style TargetType="ToolTip" x:Key="ButtonTooltip">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Border Background="LightYellow" BorderThickness="0.5" BorderBrush="Maroon" DataContext="{Binding Path=DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ToolTip}}}">
<StackPanel Orientation="Vertical" Margin="3">
<TextBlock x:Name="_txtText" Text="{Binding Title}"></TextBlock>
<TextBlock x:Name="_txtDescription" Margin="0 10 0 0" Text="{Binding Description}"></TextBlock>
<TextBlock x:Name="_txtHotKeyDescription" Margin="0 10 0 0" Text="{Binding HotKeyDescription}"></TextBlock>
</StackPanel>
</Border>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>