MultiDataTrigger.Conditions Binding to UserControl specified in another xaml file - validation

Is it possible to create TabItem MultiTrigger that will bind to Valiation.HasError property from a control that:
is a part of another UserControl
UserControl is defined in another xaml file
UserControl is a child of TabItem where MultTrigger is defined
Main xaml file:
<telerik:RadTabItem Header="Data">
<telerik:RadTabItem.Style>
<Style TargetType="{x:Type telerik:RadTabItem}" BasedOn="{StaticResource {x:Type telerik:RadTabItem}}">
<Setter Property="HeaderTemplate" Value="{StaticResource TabItemErrorTemplate}"/>
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<!-- does not work -->
<Condition Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:EquipmentDetailsTabBasicData}}, Path=InputName.(Validation.HasError)}" Value="False"/>
<!-- works only if UserControl content is inculded directly in TabItem -->
<Condition Binding="{Binding ElementName=InputPiecesCount}, Path=(Validation.HasError)}" Value="False"/>
</MultiDataTrigger.Conditions>
<Setter Property="HeaderTemplate" Value="{StaticResource TabItemTemplate}"/>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</telerik:RadTabItem.Style>
<local:EquipmentDetailsTabBasicData x:Name="TabBasicData"/>
</telerik:RadTabItem>
local:EquipmentDetailsTabBasicData xaml file looks like this:
<UserControl>
<Grid>
<telerik:RadMaskedTextInput
x:Name="InputName"
Value="{Binding Name, ValidatesOnDataErrors=True, NotifyOnValidationError=True}"/>
<telerik:RadMaskedNumericInput
x:Name="InputPiecesCount"
Value="{Binding PiecesCount, ValidatesOnDataErrors=True, NotifyOnValidationError=True, Mode=TwoWay}"
/>
</Grid>
</UserControl>
MultDataTrigger conditions shows my attempts to bind to controls in child UserControl - both do not work.
I can just move UserControl contents to RadTabItem. When I do the second version (binding by ElementName) works OK. I would like to avoid it because it makes my xaml file hard to maintain.
The first version is taken from this answer, but it does not work and I think that because UserControl is not an ancestor of RadTabItem.

Related

How to use same string resource for different item types

I have a String called Products.Label which is use for an AppBarButton. How can I use the same string for a TextBox without the app crashing?
MainPage.xaml
...
<AppBarButton Name="AppBarButtonProducts" x:Uid="Products"/>
...
Settings.xaml
...
<TextBlock x:Uid="Products/Label" Style="{StaticResource HeaderTextBlockStyle}" />
...
How to use same string resource for different item types
You could make x:string resource in the application resource for different control like the following.
<Application.Resources>
<x:String x:Key="Placeholder">Placeholder Content</x:String>
</Application.Resources>
<TextBox
Height="44"
PlaceholderText="dddd"
Text="{StaticResource Placeholder}"
/>

UWP Toolkit DataGrid Cells Padding/Margin

I'm struggling to remove/clear the padding/margin of DataGrid cells.
Appreciate if anyone can help how to remove the padding/margin. I'm using DataGridTextColumn because I need the TextBox for editing the value. I have manage to remove the padding/margin for the TextBox by setting the style for EditingElementStyle, that is;
<Style x:Key="tbEntry" TargetType="TextBox">
<Setter Property="Padding" Value="5" />
<Setter Property="Margin" Value="0" />
<Setter Property="Width" Value="45" />
</Style>
However, I cannot change the styles padding/margin for the cells after the TextBox unfocus. I have try setting on CellStyle or ElementStye of DataGridTextColumn with no luck.
What about this example?
xmlns:toolkit="using:Microsoft.Toolkit.Uwp.UI.Controls"
...
<toolkit:DataGridTemplateColumn Header="Lng" Tag="Lng">
<toolkit:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Lng, Mode=OneWay}" Margin="1,1,1,1" Padding="1,1,1,1">
</TextBlock>
</DataTemplate>
</toolkit:DataGridTemplateColumn.CellTemplate>
</toolkit:DataGridTemplateColumn>
Riza, you can control the margin used in non-editing mode by using a custom text column instead of the DataGridTextColumn. Use this one:
public class MyDataGridTextColumn : DataGridTextColumn
{
public MyDataGridTextColumn()
{
}
protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem)
{
TextBlock textBlock = base.GenerateElement(cell, dataItem) as TextBlock;
textBlock.Margin = new Thickness(2, 0, 2, 0);
return textBlock;
}
}
...and adjust the margin as you wish. Thanks.

Text Style not applied when Xamarin Forms is initialized

I have a UWP app and try out Embedded Xamarin Forms. The embedding itself works so far. But I noticed that certain TextStyles do no longer work after I initialized Forms.
Without Forms:
After Forms.Init:
The only difference is this Line in the App.xaml.cs:
Xamarin.Forms.Forms.Init(e);
The Code of the TextBlock is:
<TextBlock x:Name="TitlePage"
Text="Hello"
Style="{StaticResource PageTitleStyle}" />
And the style:
<Style x:Key="PageTitleStyle"
TargetType="TextBlock">
<Setter Property="VerticalAlignment"
Value="Center" />
<Setter Property="FontWeight"
Value="SemiLight" />
<Setter Property="FontSize"
Value="{StaticResource LargeFontSize}" />
<Setter Property="TextTrimming"
Value="CharacterEllipsis" />
<Setter Property="TextWrapping"
Value="NoWrap" />
<Setter Property="Margin"
Value="{StaticResource PageTitleMargin}" />
</Style>
I created a minimal example which you can find here: https://github.com/NPadrutt/EmbeddedFormsTest
Versions:
VS 15.5.2
Xamarin.Forms 2.5.0.121934
Microsoft.NETCore.UniversalWindowsPlatform 6.0.5
When you execute Xamarin.Forms.Forms.Init(e);, it will load the ResourceDictionary which defined in Xamarin. So that after this code line invoked, the text may show the style defined in Xamarin Forms, not the style you defined in UWP. Details you can check the code snippet of Init method.
Updated:
The Init method merge the style by this code line
return new Windows.UI.Xaml.ResourceDictionary {
Source = new Uri("ms-appx:///Xamarin.Forms.Platform.UAP/Resources.xbf")
And you will find the following style in Resource.xaml in Xamarin.
<Style x:Key="PageTitleStyle" TargetType="TextBlock">
<Setter Property="FontWeight" Value="Bold" />
</Style>
Which has same x:key (PageTitleStyle) as you defined so that your style will be override. Just change the x:key of your style it will not be influenced by the Xamarin resources,for example PageTitleStyle2.
If you want to use the style you defined in UWP app for the Xamarin Forms, you could use Custom Renderers. TextBlock is the native control for UWP, the correspondent control in Xamarin Forms is Label. Details please see Renderer Base Classes and Native Controls. You should have a Label control in Xamarin Forms and create a custom renderer for Label and set the style with target type is TextBlock in UWP. For example:
public class MyLabelRenderer : LabelRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
Control.Style= (Windows.UI.Xaml.Style)App.Current.Resources["PageTitleStyle"];
}
}
For more samples you could reference this.

Add behavior to style setter

i'm new Xamarin, can anyone suggest, how to add behaviors to the style of control in Xamarin xaml.
I have some ClickableImageBehavior and some imageBaseStyle, how to associate behavior with setter?
UPD
Details:
So... problem:
public class ClickableImageBehavior : Behavior<Image>
{
// handle user tap on button.
}
And using looks like this:
<Image>
<Image.Behaviors>
<view:ClickableImageBehavior/>
</Image.Behaviors>
</Image>
But i don't want to write this xaml on every button that has ClickableImageBehavior
I want to create some base style with this behavior and base properties and simple inherit it in every image like
<Image style="{StaticResource clickableImageStyle"/>
In WPF i can deal with it like in this article, but how to do it in Xamarin xaml?
I'm not really an expert but when I added a behaviours it was always in a component like
<psc:EnumBindablePicker x:Name="enumpickerSpeechPart">
<psc:EnumBindablePicker.Behaviors>
<pscv:PickerBehavior x:Name="pickerBehaviorSpeechPart" />
</psc:EnumBindablePicker.Behaviors>
</psc:EnumBindablePicker>
In the ResourceDictionary you can add calls to converters.
<local:BooleanToObjectConverter x:Key="boolToStyleImage" x:TypeArguments="Style">
<local:BooleanToObjectConverter.FalseObject>
<Style TargetType="Image">
<Setter Property="HeightRequest" Value="20" />
<Setter Property="Source" Value="{local:ImageResource Images.error.png}" />
</Style>
</local:BooleanToObjectConverter.FalseObject>
<local:BooleanToObjectConverter.TrueObject>
<Style TargetType="Image">
<Setter Property="HeightRequest" Value="20" />
<Setter Property="Source" Value="{local:ImageResource Images.success.png}" />
</Style>
</local:BooleanToObjectConverter.TrueObject>
</local:BooleanToObjectConverter>

Default Validation Template not getting fired in WPF

My code goes as follows :
<TextBox >
<TextBox.Text>
<Binding Path="SaveAsText" ValidatesOnDataErrors="True" ValidatesOnExceptions="True" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<val:SaveTextValidator></val:SaveTextValidator>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={x:Static RelativeSource.Self},
Path=(Validation.Errors), Converter={StaticResource errorConverter}}"/>
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
Now when a validation error happens, the ToolTip is getting displayed but the default validation template of making a TextBox border red is not firing !!
Where am I going wrong?
You are overwriting the default style of the TextBox (basically saying: do nothing unless I tell you to).
I imagine there is some trigger in the default style that makes the border red. Either implement it your self or base your style on the current default.
<Style BasedOn={x:Type TextBox} ...>

Resources