I use Visual Studio 2019 with WPF / MVVM.
I have set a trigger to a textbox to control its visibiliy.
And during runtime this works well, the trigger checks the state of a radiobutton and sets the visibiliy of the textbox accoring to the radiobutton's state.
But during designtime this textbox is not visible.
How could I make this textbox to be visible during designtime ?
This is the XAML I have for the trigger:
<Style x:Key="text" TargetType="TextBox">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=Radiobutton1, Path=IsChecked}" Value="true">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=Radiobutton1, Path=IsChecked}" Value="false">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
<TextBox Style="{StaticResource text}" Text="test..... />
I found this article https://social.msdn.microsoft.com/Forums/en-US/cacc5c30-8aa0-43c5-ad07-b063028653a2/designmode-and-visibility?forum=wpf and did some tests using "DesignerProperties.IsInDesignMode" but I can not make this run,I get errors like "datatrigger can not be added to setterbasecollection".
Also I don't know if "DesignerProperties.IsInDesignMode" is the right approach...
I think the answer is even simpler. By adding d:Visibility="Visible", the textbox will be visible at design time.
<TextBox d:Visibility="Visible" Style="{StaticResource text}" Text="test..... />
This is a workaround:
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=Radiobutton1, Path=IsChecked}" Value="true">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=Radiobutton1, Path=IsChecked}" Value="false">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
<DataTrigger Binding="{Binding Designtime}" Value="true">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
then in Viewmodel:
public bool Designtime { get; set; }
public ViewModel()
{
if (DesignerProperties.GetIsInDesignMode(new DependencyObject()))
{
Designtime = true;
}
}
And in the Window Tag
d:DataContext="{d:DesignInstance {x:Type local:ViewModel},IsDesignTimeCreatable=True}"
You can use the Blend namespace IsHidden attribute:
add the Blend namespace if missing: xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
add the d:IsHidden="True" attribute on the element you want to hide at design time
Example:
<TextBox Style="{StaticResource text}" Text="test....." d:IsHidden="True"/>
Related
I have a little problem with my code. I have a content control that I want to switch the visibility on, based on a value of a property.
I have a toggle button that changes the value of the property IsListView and the icon without a problem.
<ToggleButton Width="26" Height="26" VerticalAlignment="Center" IsChecked="{Binding IsListView}" Command="{Binding SetItemsViewStyle}" Margin="0,0,5,0">
<ToggleButton.Style>
<Style TargetType="{x:Type ToggleButton}" BasedOn="{StaticResource MahApps.Styles.Button.Circle}">
<Setter Property="Content" Value="{iconPacks:BootstrapIcons List, Width=12, Height=12}" />
<Setter Property="ToolTip" Value="Switch to list display"/>
<Style.Triggers>
<Trigger Property="IsChecked" Value="true">
<Setter Property="Content" Value="{iconPacks:Material Apps, Width=12, Height=12}" />
<Setter Property="ToolTip" Value="Switch to tile display"/>
</Trigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
</ToggleButton>
Then I have a style for the content control that I would like to hide or display depending on the value of the IsListView property:
<Style x:Key="ListViewStyle" TargetType="ContentControl">
<Setter Property="Visibility" Value="Collapsed"/>
<Setter Property="Content" Value="{x:Null}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsListView}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
<Setter Property="Content">
<Setter.Value>
<ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalAlignment="Stretch" VerticalScrollBarVisibility="Auto" Margin="0,31,0,0" >
<DataGrid ItemsSource="{Binding Projects}"/>
</ScrollViewer>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
The ContentControl is pretty much empty:
<ContentControl Style="{StaticResource ListViewStyle}">
</ContentControl>
The contents are displayed correctly when the screen is initialized (the IsListView is initialized to true), but the ContentControl does not dissapear when I click the toggle button. The code behind is executed, including fetching data from the data store, but the screen is not refreshed it seems to me.
What am I missing?
Ok, I found out what was the problem. I should have mentioned in my question that I am using ReactiveUI.
I had a property IsListView that was defined like this:
public bool IsListView { get; set; }
It has to be defined like this to ensure that the events are propagated to the view.
private bool _isListView;
public bool IsListView
{
get { return _isListView; }
set { this.RaiseAndSetIfChanged(ref _isListView, value); }
}
Now the controls hide and show as per my requirement.
I am a noob at Xaml triggers.
Do you see any obvious reason why this trigger does not work:
<TextBox Text="{Binding TiretNom}" Margin="1">
<TextBox.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding TiretNom}" Value="">
<Setter Property="TextBox.Background" Value="Tomato"/>
</DataTrigger>
<DataTrigger Binding="{Binding TiretNom}" Value="a">
<Setter Property="TextBox.BorderBrush" Value="Green"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
Neither does the backround change when the property TiretNom = "",
nor does the borderbrush gets red if TiretNom = "a"
Thx in advance.
I have a TextBlock and I want to set the property Visibility to Collapsed when the TextBlock has no text. I wonder me, for sure there should be a better way to check if the Lenght of the property Text is equal than 0.
<TextBlock Name="TextBlockHeader" Foreground="White" FontSize="18" FontWeight="Bold" Text="{Binding Header}" Margin="0,0,0,25">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=TextBlockHeader, Path=Text.Length}" Value="0">
<Setter Property="Visibility" Value="Collapsed"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
Here I have to define a name for the TextBlock and I can reference it in the Datatrigger Binding="{Binding ElementName=TextBlockHeader, Path=Text.Length}"
But how can I achieve the same without having to define a name for the TextBlock?
You would usually use Triggers instead of DataTriggers, and compare the Text property to either null or an empty string.
<Style TargetType="TextBlock">
<Style.Triggers>
<Trigger Property="Text" Value="{x:Null}">
<Setter Property="Visibility" Value="Collapsed"/>
</Trigger>
<Trigger Property="Text" Value="">
<Setter Property="Visibility" Value="Collapsed"/>
</Trigger>
</Style.Triggers>
</Style>
As the TextBlock class seems to coerce the Text property value to be non-null, it may be sufficient to have only the second Trigger for an empty string.
I need to do a component where checkboxes change into radiobuttons when certain property changes. I have no idea how to do that kind of change in xaml. The checkbox is in a datatemplate as shown below. Now I just need some kind of logic to change it into a radiobutton.
<DataTemplate>
<CheckBox IsChecked="{Binding IsSelected.Value, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</DataTemplate>
Especially when there are a lot of instances, the solution of having both controls within the DataTemplate and changing visibility might not be ideal considering performance and memory usage. In this case, a DataTemplateSelector might do the trick - see this tutorial
you can put both CheckBox and RadioButton in one container (StackPanel for example) in DataTemplate and just collapse one of them according to your condition using DataTrigger.
i hope it'll help you. sorry for my pure english.
<DataTemplate>
<StackPanel>
<CheckBox Content="CheckBoxHeader">
<CheckBox.Style>
<Style TargetType="CheckBox">
<Setter Property="Visibility" Value="Visible"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Condition}" Value="True">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</CheckBox.Style>
</CheckBox>
<RadioButton Content="RadioButtonHeader">
<RadioButton.Style>
<Style TargetType="RadioButton">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Condition}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</RadioButton.Style>
</RadioButton>
</StackPanel>
</DataTemplate>
I have a usercontrol (customized ComboBox) which I am including in another usercontrol. I want to set a style on that Customized ComboBox UserControl based on the data in the main usercontrol in which I am including my ComboBox Usercontrol.
Here is my Code
<MultiSelectComboBox:MultiUnitSelectControl x:Name="MultiUnitCombo" Grid.Row="0" Width="90" Grid.Column="0" ItemsSource="{Binding LstUnit}" Margin="0,10,0,2" FontWeight="Bold" HorizontalAlignment="Left">
<MultiSelectComboBox:MultiUnitSelectControl.Style>
<Style TargetType="{x:Type ComboBox}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Items.Count,ElementName=UnitCombo}" Value="1">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</MultiSelectComboBox:MultiUnitSelectControl.Style>
</MultiSelectComboBox:MultiUnitSelectControl>
This is my customized usercontrol. Now what I want is I want to Collapse it when the Items Count is equal to 1. UnitCombo is a combobox in my main UserControl based on its itemsCount I want to set the Visibility on the Included UserControl.
however when I apply this Style to the ComboBox in the Main UserControl It works
<ComboBox.Style>
<Style TargetType="{x:Type ComboBox}">
<Style.Triggers>
<DataTrigger
Binding="{Binding Path=Items.Count, ElementName=UnitCombo}"
Value="1">
<Setter Property="SelectedIndex" Value="0" />
</DataTrigger>
</Style.Triggers>
</Style>
</ComboBox.Style>
But applying the same style on the Included UserControl doesnt show up anything.It kind of Hangs the whole view and shows nothing as if the controls are Hidden or something.
How can I do this?
I hope you are filling your UnitCombo by setting its ItemsSource to an ObservableCollection, then you will need to bind to ItemsSource.Count instead of Items.Count.
<DataTrigger Binding="{Binding Path=ItemsSource.Count,ElementName=UnitCombo}" Value="1">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
It will work.