Datepicker Watermark - vb.net

I found this answer in Stackoverflow for Removing Datepicker Watermark.
<Style TargetType="{x:Type toolkit:DatePickerTextBox}">
<Setter Property="Text" Value="Bitte wählen" />
</Style>
is it possible to set above using vb.net code.
Thank you,
Rey.

The one way I can think of to do this is using a resource dictionary.
Create a resource dictionary with that bit of XAML in it and add the dictionary to your resources on Window Initialized. This is a nice way to change styles dynamically in WPF.
In Visual Studio, add a new Resource Dictionary and make it look like this:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:toolkit="http://schemas.microsoft.com/wpf/2008/toolkit"
>
<Style TargetType="{x:Type toolkit:DatePickerTextBox}">
<Setter Property="Text" Value="Test" />
</Style>
</ResourceDictionary>
Then in your window add the following to add the resource dictionary to your apps resources:
Private Sub Window1_Initialized(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Initialized
Dim rd As New ResourceDictionary()
rd = CType(Application.LoadComponent(New Uri("Dictionary1.xaml", UriKind.Relative)), ResourceDictionary)
Application.Current.Resources.MergedDictionaries.Clear()
Application.Current.Resources.MergedDictionaries.Add(rd)
End Sub
If you don't want to use styles the only thing that seems to make sense then is to override the default implementation of the DatePicker and implement your own. A good description of how to do that can be found here:
http://www.tanguay.info/web/index.php?pg=codeExamples&id=144

Related

How to apply styles to all inner elements in MAUI on state change

This is basically simple UI that would conditionally render a label with text Triggered - plain in case the ShowContent property of binding is True. (Overly simplified example here but it works and I can see the label toggles).
<Grid>
<Button Click="ChangeState"/>
<ContentView>
<ContentView.Style>
<Style TargetType="ContentView">
<Style.Triggers>
<DataTrigger Binding="{Binding ShowContent}" Value="True" TargetType="ContentView">
<Setter Property="ControlTemplate">
<Setter.Value>
<ControlTemplate>
<Label>Triggered - Plain</Label>
</ControlTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentView.Style>
</ContentView>
</Grid>
There is also a button that would toggle the state of the Grid:
public void ChangeState(object sender, EventArgs e){
this.state = !this.state; // toggle
if(this.state){
VisualStateManager.GoToState(this, VisualStateManager.CommonStates.Selected);
} else {
VisualStateManager.GoToState(this, VisualStateManager.CommonStates.Normal);
}
}
Problem
I am not sure how to apply a different style to the label based on selected state.
If you use VisualStateManager, you need to have a name on the Label. I want to apply selected style in a blanket way on all inner labels.
Also, if we target the label with a name, when the Label is not on the UI (due to state ShowContent being False), GoToState fails with null exception as it cannot find the label.
The best solution seems to be using CSS but that does not support defined colors and dynamic resources (AFAIK).
Any idea what to do?
Update: one possible solution is to apply the state change to all inner elements:
private IList<T> FindAllChildren<T>()
where T : IVisualTreeElement
{
return this.GetVisualTreeDescendants()
.Where(e => e is T)
.Cast<T>()
.ToList();
}
private void ApplyState(string state)
{
VisualStateManager.GoToState(this, state);
FindAllChildren<VisualElement>().ForEach(e => VisualStateManager.GoToState(e, state));
}
public void ChangeState(object sender, EventArgs e){
this.state = !this.state; // toggle
if(this.state){
ApplyState(VisualStateManager.CommonStates.Selected);
} else {
ApplyState(VisualStateManager.CommonStates.Normal);
}
}
You still need to create VisualStateGroup styling for the labels and give labels a specific style/class:
<label class="Selectable">...</label>
<Style class="Selectable" TargetType="Label">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup Name="all">
<VisualState Name="Normal">
<VisualState.Setters>
<Setter Property="Label.TextColor" Value="{DynamicResource Normal_Color}"/>
</VisualState.Setters>
</VisualState>
<VisualState Name="Selected">
<VisualState.Setters>
<Setter Property="Label.TextColor" Value="{StaticResource Selected_Color}"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
I recommend that you work around this. Too many bugs, and too different behavior on the different platforms for containers.
Fixing the visual state is one thing. Then you need to fix "IsEnabled" for child problem. After that if you change the visibility, you will notice that on IOS it is doing one thing, on android - another. (You will start losing this visual state from time to time). At some point you will start looking for ways to force the page to redraw itself.
My advice is, for now, give up on this idea. Until those problems are solved. Wasted too many hours trying to make this work for all platforms.
(Some of the issues are 6+ months old, and they keep pushing them to backlog.)
This is me, asking the same thing, a month ago: Pass the VisualState of CollectionView Item VisualElement to its child VisualElements
Edit: So, what work arounds I use.
Besides styles, visual states, data triggers?
ControlTemplates and Messages between ViewModel <-> View.
Control templates are reusable pieces of user interface, and there isn't much you have to do. You can make all VisualElements bind to the same thing, using TemplatedParent as BindingContext of the container.
Messages I use for some sorts of animations (And other special requests). You can in the ViewModel generate a message, that will be handled (or not) by the View. You have very good control over your View, but you do not break MVVM by coupling them.
A Warning: Every work around is parasitic code (you do something the wrong way, because someone else has been doing his job the wrong way). That code sooner or later will have to be deleted/replaced. Mark it with TODO, because it may take huge part of your app, and later it will be hard to find out all usage places. For now test on IOS. It takes much less work to make it work on IOS, then fix Android, than the other way around.

Change Text of Xamarin Forms Label based on bool value

I am trying to have a label which can have two different text values. I will display one of the two based on a bool. I am aware that I can create a binding to my viewmodel which could have a property (e.g. LabelText) which can be changed. However I would need to set the text inside the viewmodel in that case and that feels a bit messy.
I am looking for some kind of converter (IValueConverter) that binds a bool on the text property and has two string Parameters. The converter then chooses the right string for the Text of the label. However, to my knowledge, it is not possible to have more than one parameter on a converter?
Any Ideas how to solve this in a clean fashion? Maybe somehow by subclassing Label, but how?
I would more prefer the Trigger on this case than the IValueConverter. Because with trigger you can have your Text inside the view itself. So If you want to change; you don't have to go find the logic outside of that label.
<Label Text="Hello World!">
<Label.Triggers>
<DataTrigger TargetType="Label" Binding="{Binding IsActive}" Value="false">
<Setter Property="Text" Value="Not Active" />
</DataTrigger>
<DataTrigger TargetType="Label" Binding="{Binding IsActive}" Value="true">
<Setter Property="Text" Value="Active" />
</DataTrigger>
</Label.Triggers>
</Label>
So here you are binding the Trigger with your Boolean property in your VM. If its True or False whenever it changes it would trig that trigger.
Just to let you know; You can even change other properties too! Lets say If you want to change the Color as well ? So this could be even more better solution for you than to use ValueConverter in this case.
Hope this helps. Let me know If you need more help.

ItemsControl Freezes UI on Element Generation

I have an ObservableCollection binded to a ItemsControl inside a PivotItem.
I've made it so the ObservableCollection gets items added silently, only triggering the notificationchanged when it's done.
The Problem comes when generating the items. I've tested the codebehin and everything is completed in a timely manner, however the UI freezes when the items are generated.
This is the template for these ItemsControls:
<Style TargetType="ItemsControl">
<Style.Setters>
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="ItemTemplate" Value="{StaticResource TempCell}" />
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<VariableSizedWrapGrid />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
The problem seems to be with ItemTemplate, even if i add an empty control to the DataTemplate associated with it, it freezes the UI. Not if there is no ItemTemplate.
I'm adding several thousands controls, that will all be displayed at once, simple ToggleButtons 25x25 in size.
I've ran very similar code in WPF, before converting it to UWP and had no freezing issues.
The application runs smoothly after the generation process.
On request here's the addition code:
'Keep in mind that the item generation happens in a separate thread
Await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, Sub() List.Replace(Output))
'That's why it has to replace the old collection with the new one silently
'This code does not produce any bottleneck in WPF
Public Sub Replace(list As IEnumerable(Of T))
If list Is Nothing Then
Throw New ArgumentNullException("list")
End If
_suppressNotification = True
Clear()
For Each item As T In list
Add(item)
Next
_suppressNotification = False
OnCollectionChanged(New Specialized.NotifyCollectionChangedEventArgs(Specialized.NotifyCollectionChangedAction.Reset))
End Sub
'Scratching the code above and just trying this, i get the same result, it freezes the UI as UWP elements are being generated, here they are added one by one, which should cause notificationchanged events to occur.
Await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, Sub()
List.Clear()
For Each Item In Output
List.Add(Item)
Next
End Sub)
'These are the items generated, they refer to a global Random, changing it to a local Random, does not impact the freezing one way or the other.
Parallel.For(0, CellsCount, Sub(i) Output.Add(New Cell With {.Color = Color.FromArgb(255, CByte(Random.Next(0, 256)), CByte(Random.Next(0, 256)), CByte(Random.Next(0, 256)))}))

Change size of a WatermarkText into a WatermarkTextBox with WinRT XAML Toolkit

I use this lib : http://winrtxamltoolkit.codeplex.com/
I want to specify the FontSize of the WatermarkText, how can I do that ?
Thanks
You can use the Watermark property instead of the WatermarkText one to put anything you want as your watermark - e.g. a TextBlock with any properties you want. You can also use the WatermarkTextStyle property when using WatermarkText and specify the Style to use with the provided watermark TextBlock - something like:
<xc:WatermarkTextBox
WatermarkText="Type something">
<xc:WatermarkTextBox.WatermarkTextStyle>
<Style
TargetType="TextBlock">
<Setter
Property="FontSize"
Value="18" />
...
You can check the sample to see some options here.

Sharing styles between several GridView controls

I need to style several GridView throughout my application with the same visual styles. This style includes customizing the ItemsPanel property as well as the GroupStyle property.
My problem is that the GroupStyle property of GridView is not a dependency property. So the code I would have liked to write (see below) does not work.
Do you know a clean way to share a style (including GroupStyle) between several GridViews?
The only thing I can think of is using a GroupStyleSelector but it's kind of stupid since there is no selection to make: it's always the same GroupStyle that's being used. Moreover, I suspect it wouldn't be reflected at design time in VS & Blend.
The code I would love to use:
<GridView
ItemsSource="..."
ItemTemplate="..."
Style="{StaticResource MainMenuStyle}"/>
<Style TargetType="GridView" x:Key="MainMenuStyle">
<Setter Property="ItemsPanel">
<Setter.Value>
...
</Setter.Value>
</Setter>
<Setter Property="GroupStyle">
<Setter.Value>
<GroupStyle>
...
</GroupStyle>
</Setter.Value>
</Setter>
</Style>
I've got a magical happy solution.
You can create a custom Attached Property that you set in the Style, and upon setting it internally sets the GroupStyle property on the GridView.
Attached Property:
// Workaround for lack of generics in XAML
public class GroupStyleCollection : Collection<GroupStyle>
{
}
public class GroupStyleHelper
{
public static ICollection<GroupStyle> GetGroupStyle(ItemsControl obj)
{
return (ICollection<GroupStyle>)obj.GetValue(GroupStyleProperty);
}
public static void SetGroupStyle(ItemsControl obj, ICollection<GroupStyle> value)
{
obj.SetValue(GroupStyleProperty, value);
}
public static readonly DependencyProperty GroupStyleProperty =
DependencyProperty.RegisterAttached(
"GroupStyle",
typeof(ICollection<GroupStyle>),
typeof(GroupStyleHelper),
new PropertyMetadata(null, OnGroupStyleChanged));
private static void OnGroupStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
ItemsControl itemsControl = d as ItemsControl;
if (itemsControl == null)
return;
RefreshGroupStyle(itemsControl, GetGroupStyle(itemsControl));
}
private static void RefreshGroupStyle(ItemsControl itemsControl, IEnumerable<GroupStyle> groupStyle)
{
itemsControl.GroupStyle.Clear();
if (groupStyle == null)
return;
foreach (var item in groupStyle)
{
itemsControl.GroupStyle.Add(item);
}
}
}
XAML Style:
<Style TargetType="ItemsControl">
<Setter Property="GroupStyleTest:GroupStyleHelper.GroupStyle">
<Setter.Value>
<GroupStyleTest:GroupStyleCollection>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock FontWeight="Bold" FontSize="15" Text="{Binding Path=Name}" Foreground="HotPink"/>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</GroupStyleTest:GroupStyleCollection>
</Setter.Value>
</Setter>
</Style>
Disclaimer: I'm testing this in WPF rather than WinRT but it should work the same, as far as I can tell. That's also why I'm using an ItemsControl rather than GridView, but the property is ItemsControl.GroupStyle anyway.
I've a solution and that will definitely work as per your question, but though you should decide whether to use that in your case or not.
If you have to make same style of a control in all over the project, then you should make one common folder and in that folder
create one "Custom User Control" and apply all of your style and
customize it however you want.
After that when you need to apply that same kind of style on same control (any grid control) then simply add that customized user
control instead of predefined control
By doing this you'll also achieve MVC architecture and modularity.
I'm developing Windows 8 Metro app in C# with XAML, and in that whenever i wanted this approach then i always use this solution and it always works...
to create custom user control, you should use visual studio & in that right click on project -> add -> new item -> User Control
(Sorry if you couldn't find your solution here, but i think this might help...)