Xceed DateTimePicker, isEnabled time picker - c#

I using xceed components in our project.
Now what I need to do is readOnly property for timePicker.
Currently I got this:
<DockPanel LastChildFill="True" Width="Auto" MinWidth="140" Height="25" Margin="2">
<TextBlock Text="Od " TextAlignment="Right" VerticalAlignment="Center" FontSize="15"/>
<xceed:DateTimePicker Format="Custom"
FormatString="{Binding Path=CustomDateTimeFormat, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
FontSize="15" Value="{Binding Path=FromDate, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}">
</xceed:DateTimePicker>
</DockPanel>
But I want timePicker from this DateTimePicker readOnly = true or false, depend on conditions.
Im using MVVM pattern.

Set a DataTrigger that changes the IsReadOnly property based on some property in the VM:
<xctk:DateTimePicker
FontSize="15" Value="{Binding Path=FromDate, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}">
<xctk:DateTimePicker.Style>
<Style TargetType="xctk:DateTimePicker">
<Setter Property="IsReadOnly" Value="False"/>
<Style.Triggers>
<DataTrigger Binding="{Binding SomeProperty}" Value="True">
<Setter Property="IsReadOnly" Value="SomeValue"/>
</DataTrigger>
</Style.Triggers>
</Style>
</xctk:DateTimePicker.Style>
</xctk:DateTimePicker>

Related

How to control Visibility of ComboBox based on radio button is checked

I have a quick WPF question in regards to the visibility of my ComboBox with respects to whether or not a button is checked or not. The goal is that when the user checks the radio button: 'btnCurrent', the ComboBox: cboHistorySequence will be hidden, and when the button 'btnHistory' is checked, it will appear.
VIEW: Here we have the radio button 'btnCurrent' and 'btnHistory', as well as combobox cboHistorySequence.
<RadioButton x:Name="btnCurrent" IsChecked="{Binding IsCurrentSelected, UpdateSourceTrigger=PropertyChanged}" Content="Current" Grid.Column="0" Grid.Row="0"/>
<RadioButton x:Name="btnHistory" IsChecked="{Binding IsHistorySelected, UpdateSourceTrigger=PropertyChanged}" Content="History" Grid.Row="0" Grid.Column="1"/>
<StackPanel Orientation="Horizontal" Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" Margin="5,0" IsEnabled="{Binding IsHistorySelected, Converter={StaticResource EnabledConverter} }">
<TextBlock HorizontalAlignment="Left" Width="80">History Seq:</TextBlock>
<ComboBox x:Name="cboHistorySequence" Margin="16,0,0,0" Text="{Binding Path=HistorySequence, UpdateSourceTrigger=PropertyChanged}" Width="80" HorizontalAlignment="Left">
<ComboBoxItem>First</ComboBoxItem>
<ComboBoxItem>Last</ComboBoxItem>
</ComboBox>
</StackPanel>
What I have tried
My initial thought was to use something along the lines of this and bind it over to the view-model, but I have not been successful. What are yall's recommendations?
Visibility="{Binding IsShowComboBox, Converter={StaticResource VisibilityConverter}
Because you want to bind to the property of another element in your application you should use Binding.ElementName Property and Path, something like this:
<ComboBoxItem>Last</ComboBoxItem>
<ComboBox.Style>
<Style TargetType="{x:Type ComboBox}">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=btnCurrent, Path=IsChecked}" Value="True">
<Setter Property="Visibility" Value="Hidden" />
</DataTrigger>
</Style.Triggers>
</Style>
</ComboBox.Style>

wpf DataGridTemplateColumn.CellTemplate how to enable/disable checkboxes

I have a DataGrid with a DataGridTemplateColumn.CellTemplate defined like this:
<DataGridTemplateColumn>
<DataGridTemplateColumn.Header>
<CheckBox ToolTip="Select all items"
IsChecked="{Binding IsSelected}" Name="chkSelectAll" Checked="AllItem_Checked"
Unchecked="UnCheckAll_UnChecked" IsHitTestVisible="{Binding Path=IsSelected}"/>
</DataGridTemplateColumn.Header>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox HorizontalAlignment="Center" Checked="Item_Checked" Unchecked="Item_UnChecked"
IsChecked="{Binding IsSelected}" IsHitTestVisible="{Binding Path=IsSelected}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
The grid has a binding with a list of objects.
I want, that for each object in ItemsSource, that the checkbox is readonly if the IsSelected attribute is true.
I don't know how to code this; I tried Binding IsHitTestVisible property to IsSelected ItemsSource Objects attribute but it's not working.
I googled about and found some topics about Multidatatriggers but can't understand how they work.
You could use a Style with a DataTrigger that disables the CheckBox if IsSelected returns true:
<CheckBox HorizontalAlignment="Center" Checked="Item_Checked" Unchecked="Item_UnChecked" IsChecked="{Binding IsSelected}">
<CheckBox.Style>
<Style TargetType="CheckBox">
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected}" Value="True">
<Setter Property="IsEnabled" Value="False" />
</DataTrigger>
</Style.Triggers>
</Style>
</CheckBox.Style>
</CheckBox>

Change Binding depending on RadioButton

I have a textbox with an Binding to an ObservableCollection with a triple tuple and want to change the Binding depending on two radiobuttons:
XAML:
<ItemsControl ItemsSource="{Binding DataInformation, Mode=OneWay}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBox x:Name="xTextbox" Grid.Row="0"
IsReadOnly="True"
Text="{Binding Path=Item2 , Mode=OneWay}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl >
<RadioButton Grid.Row="1"
x:Name="PatoRadioButton"
Width="150"
Content="Type Pato"
Checked="PatoRadioButtonChecked" />
<RadioButton Grid.Row="2"
x:Name="FifoRadioButton"
Width="150"
Content="Type Fifo"
Checked="FifoRadioButtonChecked" />
VIEWMODEL:
private ObservableCollection<Tuple<int, string, string>> dataInformation;
public ObservableCollection<Tuple<int, string, string>> DataInformation
{
get
{
return DataInformation;
}
set
{
dataInformation = value;
NotifyPropertyChanged("DataInformation");
}
}
QUESTION:
How can I change the Text="{Binding Path=Item2 , Mode=OneWay}" of the TextBox depending on the checked RadioButton?
PatoRadioButton is checked then: Text="{Binding Path=Item2 , Mode=OneWay}"
FifoRadioButton is checked then: Text="{Binding Path=Item3 , Mode=OneWay}"
You could add 2 Triggers to the TextBox of your DataTemplate:
<DataTemplate>
<TextBox x:Name="xTextbox" Grid.Row="0" IsReadOnly="True">
<TextBox.Style>
<Style TargetType="TextBox">
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked,
ElementName=PatoRadioButton}" Value="True">
<DataTrigger.Setters>
<Setter Property="Text" Value="{Binding Path=Item2,
Mode=OneWay" />
</DataTrigger.Setters>
</DataTrigger>
<DataTrigger Binding="{Binding IsChecked,
ElementName=FifoRadioButton}" Value="True">
<DataTrigger.Setters>
<Setter Property="Text" Value="{Binding Path=Item3,
Mode=OneWay}" />
</DataTrigger.Setters>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
</DataTemplate>
The triggers will set the Binding of the TextBlock when the IsChecked property is changed.

how to trigger visibility change to child controls with a trigger

I have a databound listbox thet generates items in a datatemplate of type wrappanel with other controls within it. I would like to have the behavior to, when I change the visibility to affect differently the controls within the wrappanel
<WrapPanel Orientation="Horizontal" Tag="{Binding .}" HorizontalAlignment="Stretch" Visibility="{Binding editMode, Converter={StaticResource VisibilityConverter}}">
<Label Width="150" Content="{Binding Path=avaiableAttribute.Text}" Name="lblName"/>
<Label Width="150"
Content="{Binding Path=informationItem.ItemString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Initialized="Label_Initialized"
Name="lblText" />
<ContentPresenter MinWidth="200" MaxHeight="200" Content="{Binding ., Converter={StaticResource InformationItemConverter}, Mode=TwoWay}" HorizontalAlignment="Stretch"
Name="cpValue"
Initialized="ContentPresenter_Initialized"/>
<WrapPanel.Style>
<Style TargetType="{x:Type WrapPanel}">
<Style.Triggers>
<Trigger Property="Visibility" Value="Visible" >
<Trigger.Setters>
<Setter TargetName="lblText" Property="Visibility" Value="Collapsed" />
<Setter TargetName="cpValue" Property="Visibility" Value="Visible" />
</Trigger.Setters>
</Trigger>
</Style.Triggers>
</Style>
</WrapPanel.Style>
</WrapPanel>
I just get the following build error
the property 'targetname' does not represent a valid target for the 'setter' because an element
When using a Setter, the TargetName only applies to elements in a Template. This means your Trigger has to exist in a DataTemplate or ControlTemplate. The easiest way to do what you want to do is to create your own IValueConverter for the inverse of BooleanToVisibilityConverter (ie return Visibility.Collapsed when value is true).

How do you bind a viewmodel which implements IDataErrorInfo to a UserControl and propagate the validation errors?

I've written a UserControl that exposes a few dependency properties to modify the layout of the control (i.e. think of it as a generic type-safe editor control - so my data types are dates (edited through a date picker), enumerations (edited through a combobox) and a numeric (edited through a textbox). I've also exposed the value of the 3 editor controls as a dependency property so that it can be databound.
The controls within the usercontrol all bind to the exposed dependency properties to get their values (with appropriate converters where necessary).
This control forms a tiny piece of a larger UI which binds to a viewmodel - the value to be edited, the datatype flag for the custom control and a list of possible valid values are all bound to an object in the viewmodel.
My problem is this: I've implemented IDataErrorInfo on the viewmodel and set the controls' bindings within the custom usercontrol to have ValidatesOnDataErrors=True, NotifyOnValidationError=True but the validation is not displaying.
This is the XAML for my usercontrol (there is no other code-behind logic beyond the dependency property declarations):
<UserControl.Resources>
<!-- Converters -->
<local:ValidationBooleanToImageConverter x:Key="ValidationBooleanToImageConverter"/>
<local:ValidationErrorToStringConverter x:Key="ValidationErrorToStringConverter"/>
<local:DataTypeToVisibilityConverter DataType="Date" x:Key="DateDataTypeToVisibilityConverter"/>
<local:DataTypeToVisibilityConverter DataType="Numeric" x:Key="NumericDataTypeToVisibilityConverter"/>
<local:DataTypeToVisibilityConverter DataType="Enumeration" x:Key="EnumerationDataTypeToVisibilityConverter"/>
<local:DateToStringConverter x:Key="DateToStringConverter"/>
<!-- Styles -->
<Style TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors).CurrentItem, Converter={StaticResource ResourceKey=ValidationErrorToStringConverter}}"/>
</Trigger>
</Style.Triggers>
</Style>
</UserControl.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="16"/>
</Grid.ColumnDefinitions>
<toolkit:DatePicker Height="25" Margin="0,0,5,0" Visibility="{Binding Path=DataType, ElementName=UserControl, Converter={StaticResource ResourceKey=DateDataTypeToVisibilityConverter}}" SelectedDate="{Binding Path=Value, ElementName=UserControl, Converter={StaticResource ResourceKey=DateToStringConverter}}"/>
<ComboBox Height="25" Margin="0,0,5,0" Visibility="{Binding Path=DataType, ElementName=UserControl, Converter={StaticResource ResourceKey=EnumerationDataTypeToVisibilityConverter}}" SelectedItem="{Binding Path=Value, ElementName=UserControl, Mode=TwoWay}" ItemsSource="{Binding Path=Items, ElementName=UserControl}" />
<TextBox x:Name="_txtValue" Height="25" Margin="0,0,5,0" Visibility="{Binding Path=DataType, ElementName=UserControl, Converter={StaticResource ResourceKey=NumericDataTypeToVisibilityConverter}}" Text="{Binding Path=Value, ElementName=UserControl, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnValidationError=True}"/>
<Image Grid.Column="2" Grid.Row="0" Source="{Binding ElementName=_txtValue, Path=(Validation.HasError), Converter={StaticResource ResourceKey=ValidationBooleanToImageConverter} }" ToolTip="{Binding ElementName=_txtValue, Path=ToolTip}" Width="16" Height="16"/>
</Grid>
...and the usercontrol reference from within the larger View is...
<control:ValueEditorControl DataType="{Binding Path=ContextualSelectedTagDataType}" Items="{Binding Path=ContextualSelectedTagItems}" Value="{Binding Path=ContextualSelectedTagDataObjectValue, Mode=TwoWay}" Height="25" VerticalAlignment="Top"/>
Can anyone point me in the right direction?
Does your VM implement INotifyPropertyChanged? Even if you implement IDataErrorInfo if WPF isn't notified of changes to the VM then it won't bind to those changes.
That being said I would change your ToolTip setter to this:
<Setter Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self},
Path=(Validation.Errors)[0].ErrorContent}"/>
If you want the entire Style I would recommend this:
<Style TargetType="{x:Type TextBox}">
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<AdornedElementPlaceholder Name="controlWithError" />
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="Background" Value="LightPink"/>
<Setter Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self},
Path=(Validation.Errors)[0].ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>

Categories

Resources