Scrollbars in WPF Tab Item Issues - wpf

I have a Tab Control that has a whole set of close able tab items, each tab item has View with a that has a scroll able section(each view is the same not same instance), the issue that I am having is that if you scroll on one tab its cascades to all the other tabs, I was wandering if someone can tell me how I can stop this from happening?
Thanks All :)

This is the default behavior if your TabControl specifies a ContentTemplate.TabControls use virtualization, so they will re-use the template when you switch tabs instead of creating a new one each time.
This means the same ScrollViewer is being used regardless of which tab you are on. You can prove this by adding a Loaded event to your ScrollViewer and you'll see it only gets called once.
One way around this is to use a DataTemplate that has x:Shared="False", so it won't share the template. I have not tested to see if there are any performance issues with this.
<DataTemplate x:Key="TestTemplate" x:Shared="False">
<local:UserControl1 />
</DataTemplate>
<Style x:Key="TabItemStyle" TargetType="{x:Type TabItem}">
<Setter Property="Header" Value="Test" />
<Setter Property="ContentTemplate" Value="{StaticResource TestTemplate}" />
</Style>
...
<TabControl ItemsSource="{Binding SomeCollection}"
ItemContainerStyle="{StaticResource TabItemStyle}" />
Note that this seems to be very fussy... for example I need to put my ScrollViewer in a UserControl or it won't work. I also need to set TabItem.ContentTemplate instead of TabControl.ContentTemplate.

Related

XAML : Set Label Margin inside a DataTemplate

I have a DataTemplate directly inside a Resource Dictionary. Inside the template is a label. The margin property isn't being applied how I expected (it has no effect)
<DataTemplate x:Key="HeaderContainerStyle">
<Label Margin="10" Text="{Binding}"/>
</DataTemplate>
And I can't solve the issue with a border as it appears its illegal (?)
<DataTemplate x:Key="HeaderContainerStyle">
<Border Padding="10">
<Label Text="{Binding}"/>
</Border>
</DataTemplate>
I get an error saying cannot resolve symbol Border.
When I try to add it in a ViewCell, application throws an exception:
System.ArgumentException: Value was an invalid value for HeaderTemplate
Parameter name: value
In Xamarin.Forms there is no Border class. Instead you should use Frame class which I think is equivalent for Border in WPF.
Like #Nick said, if you want to use DataTemplates in Xamarin.Forms you need to add ViewCell in DataTemplate and then next next element inside that (for example Grid, StackLayout or Label).
If it comes to Padding, in Xamarin.Forms its only applicable for layout (e.g. Grid, StackLayout) classes. Margin can be specified for view (e.g. Label, Button) and layout classes.
Getting back to your code basing on your HeaderContainerStyle I think you are trying to create style for Label, right?
To do that in Xamarin.Forms you should add new create new Style in ResourceDictionary for specific TargetType.
Example Style for Label class:
<ResourceDictionary>
<Style x:Key="labelRedStyle" TargetType="Label">
<Setter Property="HorizontalOptions"Value="Center" />
<Setter Property="VerticalOptions" Value="Center" />
<Setter Property="FontSize" Value="15" />
<Setter Property="TextColor" Value="Black" />
<Setter Property="Margin" Value="15,10" />
</Style>
<ResourceDicrionary>
And example usage:
<Grid>
<Label Style="myLabelStyle" />
</Grid>
Let me know if it helped! Waiting for more questions :)
I'm assuming this is Xamarin.Forms and not WPF but if your DataTemplate is used by a ListView it is missing a ViewCell.
<DataTemplate x:Key="HeaderContainerStyle">
<ViewCell>
<Label Margin="10" Text="{Binding}"/>
</ViewCell>
</DataTemplate>
However, if your DataTemplate is used in your own custom control that was created then the ViewCell may not be needed and another issue with that control may be the cause of why Margin is not working.

WPF Toolkit Color Picker edit template now no available colors

I have looked for a solution to my problem on Google for hours, but there isnt much information to find.
I am using WPF Toolkit v2.2.1.
I have a Color Picker control in my WPF application, which needs to be custom styled. I am editing the control template of the Color Picker in App.xaml to apply to all color pickers.
As soon as I choose to use the template all available colors dissapear from the Color Picker. I have tried to assign new available colors from code with no success.
The Collection of colors are there, they are just not displayed it seems.
This is how the CP is defines in my mainwindow.xaml
<xctk:ColorPicker x:Name="cpRing" SelectedColorChanged="cpRing_Changed" HorizontalAlignment="Left" Margin="238,5,0,0" VerticalAlignment="Top" Height="20" Width="39" Foreground="Black"/>
The control template is too large to paste here unfortunately. But this should be easily reproduceable by adding a CP to a wpf window and rightclick it in designview and choose Edit Template. As soon as it is applied the colors will dissapear, without changing anything.
Does anybody know what to do to get the avaiable colors to display when editing the control template?
Best regards
yep, it has something wrong with it's style. But if you observe it's style carefully you will find out the problem:
search key word StandardColors or AvailableColors in xaml, here is StandardColors's template:
<ListBox x:Name="PART_StandardColors" Grid.Row="1">
<ListBox.Style>
<Style TargetType="{x:Type ListBox}">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="ItemsPanel">
....
</ListBox.Style>
</ListBox>
you can see the listbox has not set itemsource, so you can add it by yourself:
<ListBox x:Name="PART_StandardColors" ItemsSource="{TemplateBinding StandardColors}" Grid.Row="1">
edit listbox of AvailableColors :
<ListBox x:Name="PART_AvailableColors" ItemsSource="{TemplateBinding AvailableColors}" Grid.Row="1">
now it works.

WPF - change checkbox checkmark to image (or hide) [duplicate]

This question already has answers here:
How to create a custom WPF XAML style for check box images
(2 answers)
Closed 1 year ago.
Can anyone know if there is a simple way to replace checkbox checkmark by image?
I have two images for "checked" and "unchecked" checkbox state. I don't know how to use them instead of checkmark.
I also tried to replace content with StackPanel and put Image and TextBlock inside. Images are switching by triggers. It works fine but I have no idea how to remove checkmark icon.
I googled a lot and found complicated solutions with tons of XAML (BulletDecorator etc). I personaly don't like to complicate my life and I believe there is a simplier solution.
You could simply define your own ControlTemplate for the Checkbox, in which you display your images instead of the default tick. You can find the default ControlTemplate for the Checkbox in the CheckBox Styles and Templates page on MSDN.
When defining your own ControlTemplate, it's often a good idea to start with the default. Get that working in your project and then you can start tweaking it to your liking. That way, it should keep all the default behaviours that users are used to from a Checkbox.
But this is WPF we're talking about here... with a little lateral thinking, it's easily possible to make several controls look like other controls. For example, here is a ToggleButton with a custom ControlTemplate that makes it look like a Checkbox, but with an Image that changes when you click on it instead of the normal tick mark:
<ToggleButton Content="I'm An Image CheckBox Label" Foreground="Black">
<ToggleButton.Template>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<StackPanel Orientation="Horizontal">
<Image>
<Image.Style>
<Style>
<Setter Property="Image.Source"
Value="/AppName;component/Images/Image1.jpg" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked,
RelativeSource={RelativeSource AncestorType=
{x:Type ToggleButton}}}" Value="True">
<Setter Property="Image.Source"
Value="/AppName;component/Images/Image2.jpg" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
<ContentPresenter Content="{TemplateBinding Content}"
Margin="5,0,0,0" />
</StackPanel>
</ControlTemplate>
</ToggleButton.Template>
</ToggleButton>
It would also be easy to convert this to a CheckBox as that also uses the IsChecked property... you could probably even just replace all instances of the word ToggleButton with the word Checkbox and it should work.

Style is being overridden when value uses Binding

I have two styles set in my UserControl.Resources
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="white" />
</Style>
<Style TargetType="{x:Type Label}">
<Setter Property="Foreground" Value="white" />
</Style>
So that in my DataTemplate (and note that I chopped the rest off) I will have white text applied without having to change the properties on each and every Label and TextBlock element.
<DataTemplate x:Key="FileTransferItemTemplate">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<Label Content="Transferring With: " />
<TextBlock Text="{Binding Path=OtherUserName, Mode=TwoWay}" />
</StackPanel>
</DataTemplate>
What happens though(and this caused me a long nightmare where I thought I was databinding improperly because I couldn't see any changes), is when the data is bound the foreground color defaults to black. My databound text was black on a black background, and I didn't even realize for the longest time.
The only way I can override this is manually setting the Foreground="White" on the TextBlock. The Label works fine for the color, because it's not databound.
Why is this happening, and how can I fix it?
The problem is not related to binding. It just seems that the lookup of an externally defined default style from inside a DataTemplate only works for elements that are derived from Control. Since TextBlock isn't derived from Control, your default style is not found.
This page cites the following two statements given by Microsoft:
This behavior is 'By Design' and this is why. Templates are viewed as
an encapsulation boundary. Elements produced by these templates fall
within this boundary. And lookup for a style with a matching
TargetType stops at this boundary. Hence the TextBlock in the repro
which is produced through a template does not pick up the Style in
question. Whereas the TextBlock defined outside the template does.
One way to work around this problem is to give an explicit name to the
Style and reference the style by this name on the TextBlock within the
template.
and
Templates are viewed as an encapsulation boundary when looking up an
implicit style for an element which is not a subtype of Control.

How to change WPF Listbox/ListBoxItem DataTemplate for selected item WITHOUT affecting style & theming?

This question is very similar to Change WPF DataTemplate..., which I have read and implemented. It worked beautifully at first, but I ran into a problem with it.
That problem is that, when using themes in your application such as those in the WPF Futures project (e.g. Expression Dark), the ListBoxItems all revert back to the default WPF styling. This breaks the theme for those elements and, for example, produces black text on black background where the text would otherwise be white. This also affected my TreeView, and presumably would affect other similar controls.
I think this is because conflicting styles are being set for ListBox.ItemContainerStyle--one from the theme and one for switching data templates.
I've looked around for other solutions, but haven't found anything yet. Here are the leads or ideas I've had so far:
Subclassing DataTemplateSelector and setting it to ListBox.ItemTemplateSelector. (The current best bet).
Somehow, somewhere use a Trigger, DataTrigger, or EventTrigger.
Give up on themes.
Somehow hack the functionality I want into the theme.
Somehow make my custom ItemContainerStyle somehow inherit it's colors and eye candy from the theme's style. (I tried it briefly, and it didn't work.)
Here is my ListBox and related pieces:
<Window.Resources>
<DataTemplate x:Key="NormalTemplate">
...
</DataTemplate>
<DataTemplate x:Key="SelectedTemplate">
...
</DataTemplate>
</Window.Resources>
<ListBox x:Name="RegisterListBox" Grid.Row="0"
HorizontalContentAlignment="Stretch"
ItemsSource="{Binding Adjustments}">
<!-- this is from the post referenced above -->
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="ContentTemplate" Value="{StaticResource NormalTemplate}"/>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="ContentTemplate" Value="{StaticResource SelectedTemplate}"/>
</Trigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
The Listbox.DataContext is set in code to enable the ItemsSource binding.
Any ideas how I can achieve the kind of functionality described above while maintaining seamless support for themes?
Have you tried doing something like this?
<ListBox.ItemContainerStyle>
<Style
TargetType="{x:Type ListBoxItem}"
BasedOn="{StaticResource {x:Type ListBoxItem}}"> <=====
...
The idea is that the framework will first go look for a style with a key equal to typeof(ListBoxItem), it will find it in the themes, and then your style will just extend the themed one with your specific details.

Resources