Style on an Included Usercontrol - c#

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.

Related

XAML ContentControl not changing visibility

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.

WPF binding to Data template button column

I created a button column as a template column in a WPF datagrid.
When you press the button it sets the button content to the current date.
<DataGridTemplateColumn Header="Date In Source">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button x:Name="BtnDateInSource" Click="DateButton" Style="{StaticResource ReceiveWorkButton}" ></Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<Style TargetType="{x:Type Button}" x:Key="ReceiveWorkButton" >
<Setter Property="Background" Value="Green"/>
<Setter Property="Content" Value="{Binding DateInSource}"/>
<Setter Property="IsEnabled" Value="False"/>
<Style.Triggers>
<DataTrigger Binding="{Binding DateInSource}" Value="{x:Null}" >
<Setter Property="Background" Value="#A3BF3B" />
<Setter Property="Content" Value="Receive Work" />
<Setter Property="IsEnabled" Value="True"/>
</DataTrigger>
</Style.Triggers>
</Style>
The current problem is that since it is a template column I can't seem to bind it to the datasource (MVVM).
So the user presses the button, and it changes the button text to the current date/time. I now want to write that back to the database.
My MVVM observable collection is InspectionStatus in class SourceInspection.
I would like to do it in XAML but maybe it has to be done with INotifyPropertyChanged?
DatagridContext:
Code Behind:
System.Windows.Data.CollectionViewSource SourceViewSource =
((System.Windows.Data.CollectionViewSource)
(this.FindResource("SourceViewSource")));
_context.SourceInspections.Load();
SourceViewSource.Source = _context.SourceInspections.Local;
I think I figured it out, used this...
updating wpf datagrid on button click
Regards
K.

How to use WPF Validation rules on a Listbox to enable a 'OK' button

I'm new with WPF and I have a problem. I want to enable a button only if en element of a Listbox is selected, otherwise it has to be disabled. I've tried with simple Validation Rule but it doesn't worked. Can anyone give me a hint? Ty
You don't use a ValidationRule to enable a Button but you could use a Button style with a trigger that binds to the SelectedItem property of the ListBox and sets the IsEnabled property of the Button to false if the SelectedItem property of the ListBox returns a null reference, e.g.:
<ListBox x:Name="lb">
<ListBoxItem>1</ListBoxItem>
<ListBoxItem>2</ListBoxItem>
<ListBoxItem>3</ListBoxItem>
</ListBox>
<Button Content="Button">
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<DataTrigger Binding="{Binding SelectedItem, ElementName=lb}" Value="{x:Null}">
<Setter Property="IsEnabled" Value="False" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
Ok, this works well ty. But I've to enable the button when 2 conditions are satisfied (a textbox not empty and an item of the listbox selected). How can i do this?
You could add another trigger:
<ListBox x:Name="lb">
<ListBoxItem>1</ListBoxItem>
<ListBoxItem>2</ListBoxItem>
<ListBoxItem>3</ListBoxItem>
</ListBox>
<TextBox x:Name="txt" />
<Button Content="Button">
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<DataTrigger Binding="{Binding SelectedItem, ElementName=lb}" Value="{x:Null}">
<Setter Property="IsEnabled" Value="False" />
</DataTrigger>
<DataTrigger Binding="{Binding Text.Length, ElementName=txt}" Value="0">
<Setter Property="IsEnabled" Value="False" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>

How I can dynamically change a WPF control into another?

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>

Textblock DataTriggers not firing

I'm trying to bind some data to a TextBlock. The TextBlock is to display a slider bar value, and when the slider bar value has changed I want the TextBlock text to change colour to red.
My XAML is like this:
<Grid Height="227">
<TextBlock Margin="114,60,112,150" Name="textBlock1" Text="{Binding Path=DispVal}" Width="42" Grid.Column="1" HorizontalAlignment="Center" TextAlignment="Center" FontWeight="Bold">
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="Black"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsChanged}" Value="true">
<Setter Property="TextBlock.Foreground" Value="Red" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=IsChanged}" Value="false">
<Setter Property="TextBlock.Foreground" Value="Black" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</Grid>
I have bound the TextBlock using DataContext:
texBlock1.DataContext = m_slider;
I update the m_slider object when my slider bar update handler fires.
However, I don't get any text or colour changes.
you could replace textblock with textbox and make it similar in look and feel by applying the following properties
<Setter Property="IsReadOnly" Value="True"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
Then you can use the TextChanged event in order to update its style any time text is changed by your binding

Categories

Resources