How to disable validation of a combox element when visibility is collapsed? - c#

I want to disable the validation of a ComboBox or a TextBox when their visibility is collapsed. Can I realize this within the XAML code?
<ComboBox Name="XYZCb" ItemsSource="{Binding XYZ}" Visibility="{Binding IsVisible, Converter={StaticResource BoolToVisibilityConverter}}">
<ComboBox.Text>
<Binding Path="xyz" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<valid:ValidationRule ValidatesOnTargetUpdated="True"/>
</Binding.ValidationRules>
</Binding>
</ComboBox.Text>
</ComboBox>
Button property binding:
<Button.IsEnabled>
<MultiBinding Converter="{StaticResource InverseAndBooleansToBooleanConverter}"
Mode="TwoWay">
<Binding ElementName="XYZCb" Path="(Validation.HasError)"/>
</MultiBinding>
<Button.IsEnabled>

If I understand correctly what you need:
<Button>
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=(Validation.HasError), ElementName=XYZCb}" Value="True"/>
<Condition Binding="{Binding Visibility, ElementName=XYZCb}" Value="Visible"/>
</MultiDataTrigger.Conditions>
<Setter Property="IsEnabled" Value="False"/>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
Don't forget to remove your <Button.IsEnabled> binding.

Related

User Prism Library With WPF, DataTrigger can not be triggered in ItemContainerStyle. Any Suggestion to get Instance of ViewModel

In MVVM pattern without Prism Library with WPF , view model is injected in manually. DataTrigger Path can be specified by
Path=DataContext.ColumnColorSlideStatus}". It works fine.
<Window.DataContext>
<local:ViewModel />
</Window.DataContext>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type ListView}}, **Path=DataContext.ColumnColorSlideStatus}"**
Value="Review">
<Setter Property="Background">
<Setter.Value>
<Binding
Converter="{StaticResource ColumnBackGroundColorConverter}"
ConverterParameter="Review"
RelativeSource="{RelativeSource Self}" />
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type ListView}}, **Path=DataContext.ColumnColorSlideStatus}"**
Value="NFR">
<Setter Property="Background">
<Setter.Value>
<Binding
Converter="{StaticResource ColumnBackGroundColorConverter}"
ConverterParameter="NFR"
RelativeSource="{RelativeSource Self}" />
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
When Using Prism Library with WPF, the view and viewmodel is linked automatically by code below.
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
There is no instance of DataContext in View Xaml Code. the DataTrigger Path can not be specified to the DataContext.ColumnColorSlideStatus. DataTrigger can not be triggered.
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type ListView}}, **Path=ColumnColorSlideStatus}"**
Value="Review">
<Setter Property="Background">
<Setter.Value>
<Binding
Converter="{StaticResource ColumnBackGroundColorConverter}"
ConverterParameter="Review"
RelativeSource="{RelativeSource Self}" />
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type ListView}}, **Path=ColumnColorSlideStatus}"**
Value="NFR">
<Setter Property="Background">
<Setter.Value>
<Binding
Converter="{StaticResource ColumnBackGroundColorConverter}"
ConverterParameter="NFR"
RelativeSource="{RelativeSource Self}" />
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
```
Is any suggestions to get instance of viewmodel into view when Prism Library is used or some way works around it

WPF trigger validation of a content control to enable or disable a button

I have a UserControl with a ContentControl, which is a UserControl too.
This Content Control can be filled with any UserControl. I now want to lock a button in the parent UserControl, as long as the child UserControl doesn't have any errors.
Parrent:
The Content Control:
<ContentControl Name="SerializationLayerContentControl"
Grid.Row="1"
Grid.ColumnSpan="2"
Content="{Binding SerializationLayerConfiguration.ConfigView}">
</ContentControl>
and the button:
<Button Name="CreateTelegramBttn" Content="Create Telegram" Grid.Row="2" Click="CreateTelegramBttn_Click">
<Button.Style>
<Style TargetType="Button">
<Setter Property="IsEnabled" Value="False"/>
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=(Validation.HasError), ElementName=SerializationLayerContentControl}" Value="False"/>
</MultiDataTrigger.Conditions>
<Setter Property="IsEnabled" Value="True"/>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
<Button Name="CreateAndSaveTelegramBttn" Content="Create and save" Grid.Row="2" Grid.Column="1" Click="CreateAndSaveTelegramBttn_OnClick"></Button>
Child:
This is what I've got in the child UserControl
<ListBox Grid.ColumnSpan="2" Grid.RowSpan="3"
ItemsSource="{Binding FieldDefinitionElements}">
<ListBox.ItemTemplate>
<DataTemplate>
<DockPanel>
<Label>
<Label.Content>
<MultiBinding Converter="{StaticResource FieldDefConverter}">
<Binding Path="Element.FieldName"></Binding>
<Binding Path="Element.FieldType"></Binding>
<Binding Path="Element.FieldLength"></Binding>
</MultiBinding>
</Label.Content>
</Label>
<TextBox DockPanel.Dock="Right">
<TextBox.Resources>
<validation:BindingProxy Data="{Binding Path=Element}" x:Key="proxy"/>
</TextBox.Resources>
<TextBox.Text>
<Binding
Path="Value"
Mode="TwoWay"
UpdateSourceTrigger="PropertyChanged"
NotifyOnSourceUpdated="True"
NotifyOnTargetUpdated="True"
NotifyOnValidationError="True"
ValidatesOnDataErrors="True"
ValidatesOnNotifyDataErrors="True">
<Binding.ValidationRules>
<validation:FieldDefinitionElementRule ValidatesOnTargetUpdated="True">
<validation:FieldDefinitionElementRule.Wrapper>
<validation:Wrapper StringFormat="{Binding Path=Data.FieldType, Source={StaticResource proxy}}" IntFormat="{Binding Path=Data.FieldLength, Source={StaticResource proxy}}"/>
</validation:FieldDefinitionElementRule.Wrapper>
</validation:FieldDefinitionElementRule>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
</DockPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Currently it's not working that the button is locked when there are any errors.

Enable button when textbox is validated in WPF

I'm trying to disable/enable a button when a textbox is validated.
I get the validation to work (I know that it works because it changes design).
But I can't seem to get the button to change from disabled to enabled when the textbox is validate.
Here's my code:
<AdornerDecorator>
<TextBox Width="150"
Validation.ErrorTemplate="{StaticResource ValidationErrorTemplate}"
x:Name="OrgNoTextBox">
<TextBox.Text>
<Binding Path="Customer.OrgNo" UpdateSourceTrigger="PropertyChanged" >
<Binding.ValidationRules>
<client:RegexValidationRule ValidatesOnTargetUpdated="True" Pattern="OrgNo" />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
</AdornerDecorator>
...
<Button Width="80"
Height="25"
Margin="0 0 5 0"
Command="{Binding OkCommand}"
HorizontalAlignment="Left"
IsDefault="True"
Content="Save">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="IsEnabled" Value="false" />
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding ElementName=OrgNo, Path=(Validation.HasError)}"
Value="false" />
</MultiDataTrigger.Conditions>
<Setter Property="IsEnabled"
Value="true" />
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
Your ElementName in the MultiDataTrigger is wrong. It should be OrgNoTextBox instead of OrgNo.
like it
private void Grid_MouseMove_1(object sender, MouseEventArgs e)
{
btn.IsEnabled = false;
if (txt.IsArrangeValid == true)
{
btn.IsEnabled = true;
}
}

How to make a WPF listbox item not clickable

I am using a listbox to display a list of items that I am selecting programmatically in a voice activated program. Is there any way to keep the selected item from being clicked on? I do want mouse over functionality, just not clicking on the actual item.
I have tried to set Focusable (does not do anything for what I want) and IsEnabled (disables mouse over)
Here is my current style:
<Style x:Key="GlyphList" TargetType="ListBox">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" IsEnabled="False"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate DataType="models:SpellingGlyph">
<Label VerticalAlignment="Bottom">
<Label.Template>
<ControlTemplate>
<Grid>
<TextBlock Name="MainText" Text="{Binding Text}" VerticalAlignment="Bottom" Margin="0,0,5,0"/>
</Grid>
<ControlTemplate.Triggers>
<DataTrigger Value="True">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource ObjectReferenceEqualityConverter}">
<Binding />
<Binding Path="SelectedItem" RelativeSource="{RelativeSource FindAncestor, AncestorType=ListBox}"/>
</MultiBinding>
</DataTrigger.Binding>
<Setter TargetName="MainText" Property="Foreground" Value="#75BAFF"/>
<Setter TargetName="MainText" Property="FontWeight" Value="SemiBold"/>
<Setter TargetName="MainText" Property="FontSize" Value="22"/>
</DataTrigger>
<DataTrigger Value="True">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource MultiBooleanConverter}"> <!--SelectedItem trumps mouse over-->
<Binding ElementName="MainText" Path="IsMouseOver"/>
<Binding Path="SelectedItem" RelativeSource="{RelativeSource FindAncestor, AncestorType=ListBox}" Converter="{StaticResource InvertedNullCheckToBooleanConverter}"/>
</MultiBinding>
</DataTrigger.Binding>
<Setter TargetName="MainText" Property="Foreground" Value="#75BAFF"/>
<Setter TargetName="MainText" Property="FontWeight" Value="SemiBold"/>
<Setter TargetName="MainText" Property="FontSize" Value="22"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Label.Template>
</Label>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<ListBox PreviewMouseDown="ListBox_OnPreviewMouseDown"..
private void ListBox_OnPreviewMouseDown(object sender, MouseButtonEventArgs e)
{
e.Handled = true;
}
An alternative solution to what I accepted was to add the following in my view model:
if (_viewModelSetSelectedGlyph != value) return;
_selectedGlyph = value;
OnPropertyChanged("SelectedGlyph");
Then, set the _viewModelSetSelectedGlyph each time before actually setting the SelectedGlyph. Then, when the UI tries to set the SelectedGlyph, it would not succeed, only when the view model sets it by also setting the private variable does it succeed.
Simply set IsHitTestVisible to false
https://msdn.microsoft.com/en-us/library/system.windows.uielement.ishittestvisible(v=vs.110).aspx

Change image of a button in a datagrid cell when it is clicked - wpf

I have a WPF application which contains a Datagrid consisting of a column of buttons. The respective XAML code is as follows.
<DataGridTemplateColumn Header="Closed" Width="60">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button>
<Button.Content>
<Image>
<Image.Source>
<MultiBinding Converter="{StaticResource ImageConverter}"
ConverterParameter="Closed">
<Binding Path="IsClosed"/>
<Binding Path="DataContext.TickImage" RelativeSource="{RelativeSource AncestorType={x:Type UserControl}}"/>
<Binding Path="DataContext.CrossImage" RelativeSource="{RelativeSource AncestorType={x:Type UserControl}}"/>
</MultiBinding>
</Image.Source>
</Image>
</Button.Content>
<Button.Command>
<Binding Path="DataContext.ClosedClicked" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type UserControl}}"/>
</Button.Command>
</Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
The TickImage and CrossImage are image sources either of which is selected based on the value of IsClosed .
Now in the ViewModel I need to write a code to toggle images(b/w TickImage and CrossImage ) when the button is clicked. In other words, I need a way to simultaneously bind the Button with an ICommand and a BitmapImage variable.
Please help!!
if your IsClosed is just a toggle to know if button was pressed or release then you can achieve this by just using triggers like below:
<ToggleButton>
<ToggleButton.Content>
<Image>
<Image.Style>
<Style TargerType="Image">
<Setter Property="Source" Value="{Binding Path="DataContext.TickImage" RelativeSource="{RelativeSource AncestorType={x:Type UserControl}}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked, RelativeSource="{RelativeSource AncestorType={x:Type ToggleButton}}" Value="true">
<Setter Property="Source" Value="{Binding Path="DataContext.CrossImage" RelativeSource="{RelativeSource AncestorType={x:Type UserControl}}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</ToggleButton.Content>
</ToggleButton>

Categories