Hide selected TabIItems in WPF TabControl - wpf

I'm using the TabControl in WPF as a sort of equivalent to the ASP.Net multiview control. I need to make two of the four tabitem headers hidden. What would be the best method of doing this in XAML?

I fixed this by adding DataTriggers to my Template. If my tab is DeTached (Hidden) I set the Visibility property to Collapsed. If it's visiable again I simply set the Visibility property to Visible again.
<DataTrigger Binding="{Binding IsDetached}" Value="True">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
<DataTrigger Binding="{Binding IsDetached}" Value="False">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
Edit: Updated based on #Miklós Balogh feedback. Thanks, improved my code as well, haha. :)

Related

Style a custom WPF control when it's in a different state

I have a custom autocomplete control in WPF.It's created by combining a textbox and a dropdownlist, and a custom style for it.Looks like this ->"
The background color he has is the same even if is editable or readonly.And on my view i have more boxes and lists, they look like this ->
These are simple textboxes, and they change they're background depending on they're state: readonly or editable.
So my question is : how can i style my custom control to have that same gray background when it is in readonly mode in order to have the same standard on my view ?
I think you can use DataTrigger to get it works, like this:
<Style TargetType="YourCustomControl">
<Style.Triggers>
<DataTrigger Binding="{Binding IsReadOnly}" Value="True">
<Setter Property="Background" Value="ColorHere"/>
</DataTrigger>
<DataTrigger Binding="{Binding IsReadOnly}" Value="False">
<Setter Property="Background" Value="ColorHere"/>
</DataTrigger>
</Style.Triggers>
</Style>

How to check if any of three controls has focus at same time in wpf?

I have a three textboxes...and I wanted to check if any of these three has focus in it.
I tried something like this -> added three properties in viewmodel...whose value will be toggled by lost/got focus events. (I did this through attached properties). But in this case...if I move foucs from one textbox to next...first textbox's focus become false...and next one is yet to set...So in this condition none of these textboxes has focus...but second one will gain focus soon.
As a work around, I am trying to use Group box...to check if this control has focus instead of checking all three. Please tell me if this work
Why do you need to know if they have Focus or not?
Focus is a View-Specific function, so I would expect your ViewModels not to care about it.
Usually if I am doing something based on control Focus, it is for a View-Specific action such as a DataTrigger, and in that case I use code-behind or a Trigger
Code behind example
if (tb1.IsFocused|| tb2.IsFocused || tb3.IsFocused)
{
DoSomething();
}
Trigger example
<Style.Triggers>
<DataTrigger Binding="{Binding IsFocused, ElementName=tb1}" Value="True">
<Setter Property="BorderBrush" Value="Red" />
</DataTrigger>
<DataTrigger Binding="{Binding IsFocused, ElementName=tb2}" Value="True">
<Setter Property="BorderBrush" Value="Red" />
</DataTrigger>
<DataTrigger Binding="{Binding IsFocused, ElementName=tb3}" Value="True">
<Setter Property="BorderBrush" Value="Red" />
</DataTrigger>
</Style.Triggers>

Trigger for IsChecked does not Trigger

I want to change the Icon of a ToggleButton (Content of Fluent RibbonBar) Depending on it's IsChecked Property. Now I have written the following style snippet:
<Fluent:ToggleButton.Style>
<Style BasedOn="{StaticResource RibbonButtonStyle}" TargetType="{x:Type Fluent:ToggleButton}">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Fluent:ToggleButton}}, Path=IsChecked}" Value="False">
<Setter Property="Icon" Value="{StaticResource ResourceKey=Style.Images.Pined}"/>
</DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Fluent:ToggleButton}}, Path=IsChecked}" Value="True">
<Setter Property="Icon" Value="{StaticResource ResourceKey=Style.Images.Unpined}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Fluent:ToggleButton.Style>
The problem is that the Trigger doesn't load the Image well. The problem is not, that IsChecked doesn't actualize itself, I've already tested this. And also I don't set the icon property anywhere else. The image resources also works fine if I use them otherwhere.
Information for Rebuild: I've put the ToggleButton into the Backstage as the DataTemplate of a RibbonListBox placed in a BackstageTabItem.
Since this is a style for togglebutton you don't need a findancestor binding - you would use self. And actually since IsChecked is a DP you can just use a trigger - eg <Trigger Property="IsChecked" Value="False">
You absolutely need to remove the Icon property from the control declaration as it will override everything a style tries to do due to precedence.
But those DataTriggers will not work, the binding will look for an ancestor, itself excluded, so you must change them as well as already pointed out by AndrewS. Only if both conditions are met you have a chance of getting this to work (there may be even additional interferences though).

Calling an ElementMethod in a DataTrigger

I have a TextBox thats using this Style. I need to add a Focus() method to in this style.
So that when the TextBox is Visible and the ValidParent Property is false then i call the Focus() method on that TextBox
<Style x:Key="ParentTextBoxStyle" TargetType="{x:Type TextBox}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=ValidParent }" Value="false">
...
</DataTrigger>
<DataTrigger Binding="{Binding Path=ValidParent }" Value="false">
<Setter Property="BorderBrush" Value="Red"/>
</DataTrigger>
</Style.Triggers>
</Style>
Is this possible ?? And if it is then if i had multiple textboxes with the same behaviour which one will recieve Focus?? Does the Order of the Controls in my Xaml make a diffrence then ??
Thank you
You cannot call methods via style triggers. Using Interactivity from the Blend SDK you have more options, including method calls but they cannot be easily used in styles.

Can I make a WPF DataGridRow unselectable?

I have a style on my datagrid to disable a DataGridRow based on a property binding. This makes the row unselectable, which is what I want. However, I am still able to select the disabled rows using at least 2 other ways. The first is if I use a dragging motion between two enabled rows that surround the disabled row. The second is if I click on the "select all" button on the top left of the datagrid. Is there a way to make specific rows completely unselectable?
This is what I currently have:
<DataGrid.RowStyle>
<Style TargetType="{x:Type DataGridRow}">
<Style.Triggers>
<DataTrigger Binding="{Binding DisableMe}" Value="True">
<Setter Property="IsEnabled" Value="False" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
What about using the SelectionChanged event to undo the selection? I really don't think there is a straightforward way to it, anyway.
You could also change the row style so it appears unselected even if it IS selected, and filter it out the selection through code...
I just stumbled upon this thread with the same problem, and I want to point out that you can simply set enabled to false.
I don't think of any proper solution to this question. But as a workaround you can bind 'IsHitTestVisible' property of DataGrid to 'IsEnabled'.
<DataGrid.RowStyle>
<Style TargetType="{x:Type DataGridRow}">
<Setter Property="IsEnabled" Value="True" />
<Setter Property="IsHitTestVisible" Value="{Binding RelativeSource={RelativeSource Self},Path=IsEnabled}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding DisableMe}" Value="True">
<Setter Property="IsEnabled" Value="False" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>

Resources