Jak ve WPF zbavit DatePicker otravného hintu

Pokud jste vyvíjeli nějaký formulář ve WPF, jistě jste si všimli komponenty DatePicker. To je pole s ikonkou kalendáře, které po kliknutí rozbalí kalendář pro pohodlný výběr data. V základu ta komponenta vypadá takhle:

Tradiční DatePicker s hintem

Tradiční DatePicker s hintem

Jak vidíte, je v něm hint v angličtině, co s tím máte dělat. Tyto hinty jsou v některých polích docela užitečné, ale zrovna tady je to naprosto zbytečná věc, navíc v angličtině. A co je opravdu blbé, nedá se to změnit normálním atributem. Takže to budeme muset obejít.

Nejprve si vytvoříme statickou třídu, které předáme náš DatePicker, aby se postarala o odstranění toho vodoznaku.

DatePickerWatermark
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public static class DatePickerWatermark
{
public static void Remove(object sender)
{
var dp = sender as DatePicker;
if (dp == null) return;
var tb = GetChildOfType<System.Windows.Controls.Primitives.DatePickerTextBox>(dp);
if (tb == null) return;
var wm = tb.Template.FindName("PART_Watermark", tb) as ContentControl;
if (wm == null) return;
wm.Content = null;
}
public static T GetChildOfType<T>(DependencyObject depObj) where T : DependencyObject
{
if (depObj == null) return null;
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
var child = VisualTreeHelper.GetChild(depObj, i);
var result = (child as T) ?? GetChildOfType<T>(child);
if (result != null) return result;
}
return null;
}
}

Třida si na pomoc zavolala VisualTreeHelper, našla s jeho pomocí TextBox, vložený do komponenty a pak si našla Template s názvem PART_Watermark, jehož obsah odstranila.
Mějme tedy DatePicker, vložený do našeho formuláře…

DatePicker
XHTML
1
<DatePicker Name="Date" Width="120" Loaded="Date_Loaded" />

Kromě názvu a velikosti jsem ještě definoval reakci na událost Loaded. V této metodě zavoláme statickou třídu DatePickerWatermark s metodou Remove a předáme jí tu komponentu.

Date_Loaded
C#
1
2
3
4
private void Date_Loaded(object sender, RoutedEventArgs e)
{
DatePickerWatermark.Remove(sender);
}

No a to je vše. Vodoznak je pryč. Třídu lze libovolně rozšířit, aby třeba psala vodoznak česky, nebo tam vložila obrázek – fantazii se meze nekladou. Enjoy…

Komentování je uzavřeno.