Dragablz TabablzControl Visibility property not working - c#

I'm using dragablz:TabablzControl in a project of mine and I have the need of hide/show some tabs dinamically.
The fact is the control is not respecting the property Visibility of the TabItem.
I've tried with and without binding, like this:
<dragablz:TabablzControl Grid.Row="2" BorderThickness="0" FixedHeaderCount="20">
<TabItem Header="Additional Info" Visibility="{Binding ShowAdditionalInfoTab, Converter={StaticResource BooleanToVisibilityConverter}}">
<controls:AdditionalInfoControl />
</TabItem>
<TabItem Header="Additional Info" Visibility="Collapsed">
<controls:AdditionalInfoControl />
</TabItem>
</dragablz:TabablzControl>
But none is working. Change the "FixedHeaderCount" does not affect the result.
The tab remains always visible.
Is there any other way that I can achieve the result I need?

I've received a response from the development team, and I'm leaving it here for anyone who has the same problem.
Yeah, obviously there’s since changes to the standard tab control to support all of the extra features, and currently that’s not supported. You’d have to temporarily remove your hidden item from the source.

Related

Why do we use itemsource actually?

I am new to .net and i studied on msdn that it "represents a control that can be used to present a collection of items."
By this line what i understand is suppose if i use it for TabControl then it provides a control which will enable several TabItems (collection) to render on the given
conatiner.
<controls:TabControl Grid.Row="0" BorderThickness="0" Background="White"
ItemsSource="{Binding TabList, Mode=TwoWay, Converter={StaticResource TabConverter}}"
Could someone please correct (if i am wrong) with an example easy to understand showing why do we use it. What happen if we dont use it?
The purpose of the ItemsSource it so create a dynamic number of tabs depending on some data stored in a class (You need to set the DataContext of the Window though.
If you don't use ItemsSource, you could use separate TabItems to create a static number of tabs.
So it is this (showing a tab for each name in the list):
<TabControl ItemsSource="{Binding ListOfNames}}" />
Opposing to:
<TabControl>
<TabItem Header="John">
</TabItem>
<TabItem Header="Jane">
</TabItem>
<TabItem Header="Dave">
</TabItem>
</TabControl>

Forcing a ListBox to re-render

Background:
I have a ListBox containing items defined by DataTemplates. Right now, if an object in the list has the property IsEditable set to true, the item's property information will be displayed inside of textboxes (via DataTemplate change), instead of textblocks (so the user can edit the content of that list item)
IsEditable is toggled on/off by a button inside of each list item. I have been told that we need to keep the state of all objects consistent, which means I can't just rebind the ItemsSource and lose everything.
Currently, I'm using this to re-render:
this.lbPoints.Dispatcher.Invoke(DispatcherPriority.Render, new Action(() => { }));
Question:
The aforementioned code snippet KIND OF does its job. By "kind of", I mean, it does eventually cause my data to become re-rendered, but only when I scroll to the bottom of the list and then scroll back up to the item i'm trying to re-render.
1) How can I re-render the data immediately without having to scroll around to get it to show up?
The guys commenting are right that you're going about this the wrong way... there is rarely a need to force a ListBox to re-render. You're probably causing yourself some additional grief trying to switch the DataTemplates (although it is possible). Instead of that, think about data binding the TextBox.IsReadOnly property to your IsEditable property:
<TextBox IsReadOnly="{Binding IsEditable}" Text="{Binding Text}" />
Another alternative is to use a BooleanToVisibilityConverter to show a different Grid in your DataTemplate when your IsEditable property is true. Unfortunately, that Converter doesn't have an inverse operation, so you could create an IsNotEditing property to bind to the Grid in the DataTemplate that is originally displayed. I'm not sure if that's clear... see this example:
<DataTemplate DataType="{x:Type YourPrefix:YourDataType}">
<Grid>
<Grid Visibility="{Binding IsNotEditing, Converter={StaticResource
BooleanToVisibilityConverter}}">
<!-- Define your uneditable UI here -->
</Grid>
<Grid Visibility="{Binding IsEditing, Converter={StaticResource
BooleanToVisibilityConverter}}">
<!-- Define your editable UI here -->
</Grid>
</Grid>
</DataTemplate>
You could also define your own BooleanToVisibilityConverter class that has an IsInverted property, so that you can just use the one IsEditing property. You'd need to declare two Converters still, like this:
<Converters:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
<Converters:BoolToVisibilityConverter x:Key="InvertedBoolToVisibilityConverter"
IsInverted="True" />
Then your XAML would be like this:
<Grid Visibility="{Binding IsEditing, Converter={StaticResource
InvertedBoolToVisibilityConverter}}">
<!-- Define your uneditable UI here -->
</Grid>
<Grid Visibility="{Binding IsEditing, Converter={StaticResource
BoolToVisibilityConverter}}">
<!-- Define your editable UI here -->
</Grid>

call to page inside tab control via code

I heed to create wizard and in the wizard I have tab control which have to call to the user control according to the context,I need to create the wizard which will able to invoke
different pages according to the user selection ,currently I call to the pages as follows which I think is not the right way,any Idea how should I do it via code (not in the xaml )i.e. according to some decision invoke the suitable page to the tab control.
this is the xaml:
<Border Grid.Column="1" Name="MainBorder">
<TabControl x:Name="MainTabControl" Height="638" VerticalAlignment="Bottom">
<TabItem Visibility="Collapsed" >
<Frame Source="page1.xaml" />
</TabItem>
<TabItem Visibility="Collapsed" >
<Frame Source="page2.xaml"/>
</TabItem>
<TabItem Visibility="Collapsed" Header="Step 3">
<TextBlock Text="Page 3"/>
</TabItem>
<TabItem Visibility="Collapsed" Header="Step 4">
<TextBlock Text="Page 4"/>
</TabItem>
</TabControl>
</Border>
UPDATE
I was tried in the main window like the following without success
create new tab by code and add to it the page 1 and then add it to the MainTabControl
TabControl tabControl = new TabControl(new Page1());
MainTabControl.add..
.
there is no add in the main tab control
For this scenario, I would use a Frame rather that tabs. The frame allows you to manage the flow of it's content via the NavigationService. You can use Uri's to display a page via the Frame.Source property, or a FrameworkElement via the Frame.Content property. Both are DependencyProperties and can therefore be bound to.
Paul Stovel wrote an excellent blog on this called WPF Navigation. Everything you need to create a wizard from a frame can be found in this blog, including passing values between pages and templating of the Frame to simply handle the display of navigation buttons.
I would agree with Mark, it is a lot easier to use NavigationWindows than TabControls.
I've worked on a lot of interfaces like this and written up some of the basic things with,
WPF Wizards, Part 1
WPF Wizards, Part 2
Then more recently I worked out how to get the styling just right
Styling Wizards
In fact I've released the styling and examples as open source at
WinChrome
There is some simple example code including use of a navigation list to the left with,
WinChrome.Win7Demo
Hope this helps

WPF Issues with binding to styled button

I have created a RadioButton style which I use across my application. The display part of which uses the content presenter to display whatever content I added to the button:
<ContentPresenter>
<ContentPresenter.ContentTemplate>
<DataTemplate>
<Grid>
<TextBlock Text="{TemplateBinding Content}" />
</Grid>
</DataTemplate>
</ContentPresenter.ContentTemplate>
</ContentPresenter>
I'm then attempting to bind a decimal with a string formatter to the styled button like so:
<RadioButton Content="{Binding Stake, StringFormat={}{0:C}}" Style="{DynamicResource NeutralSelectorButtonStyle}" />
Stake is a decimal within a ViewModel which is set as the DataContext. When I run this up the content coming through is blank.
I made a change using a label in the DataTemplate rather than a TextBlock, this displayed the decimal but had not formatted it.
Can anyone explain why this is happening and possibly provide a solution.
If you require any more information just ask :)
Thanks in advance.
You are almost there just instead of setting the string format inside binding you should use ContentStringFormat property when in ContentControls.
Take a look at this Label (it works with any content control):
<Label Content="{Binding Path=MaxLevelofInvestment}" ContentStringFormat="Amount is {0}"/>
ContentPresenter also has this property:
http://msdn.microsoft.com/en-us/library/system.windows.controls.contentpresenter.contentstringformat%28v=vs.110%29.aspx
Try it out. I hope it works for you.

WPF highlighting tab headers where validation fails

I currently have a tab control containing multiple tab items, where each tab item contains different custom user control. I would like the tab headers to turn red when the associated tab contains a validation failure. My validations are implemented as ValidationRules on the appropriate bindings (moving to IDataError or another validation approach is not a feasible solution). Each tab specific control tracks it's errors through the bubbling ValidationErrorsEvent and exposes a count.
I am currently using x:Name on the tab specific controls & ElementName in the TabItem headers to bind the count exposed by the tab specific controls to the color of the text in the header (via a converter).
<TabControl>
<TabItem>
<TabItem.Header>
<TextBlock Text="Tab 1" Foreground="{Binding Errors.Count, ElementName=_tabOne, Converter={StaticResource ErrorCountToColorConverter}}" />
</TabItem.Header>
<AdornerDecorator>
<my:CustomTabOneControl x:Name="_tabOne" />
</AdornerDecorator>
</TabItem>
<TabItem>
<TabItem.Header>
<TextBlock Text="Tab 2" Foreground="{Binding Errors.Count, ElementName=_tabTwo, Converter={StaticResource ErrorCountToColorConverter}}" />
</TabItem.Header>
<AdornerDecorator>
<my:CustomTabTwoControl x:Name="_tabTwo" />
</AdornerDecorator>
</TabItem>
</TabControl>
Due to the lazyness of WPFs tab control, the validation of each tab does not occur until it is opened. As such the headers for tabs containing invalid fields do not turn red until the tab has been opened (after that they remain correct).
Can anyone suggest a way of resolving this issue, or an alternative approach to achieve the same tab highlighting?
Have a look at this post and answer; it is a lot of work and possibly maintenance but it does work by using a multitrigger that sets the header template based on the HasError property of the controls. Unfortunately it requires you to add a condition to the trigger for each control that should influence the state of the header.
You could try combine this with the answer to this post: Detecting WPF Validation Errors
that walks the visual tree to find Validation Errors. Thereby making it dynamic and less dependent on maintaining the trigger conditions when building the UI.

Categories

Resources