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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
|
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Threading;
using Tango.AutoComplete.Editors;
using Tango.SharedUI;
public static class ViewModelExtensionMethods
{
/// <summary>
/// Sets the focus to the visual element that binds to the specified property.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="vm">The view model.</param>
/// <param name="propertyLambda">The property lambda.</param>
public static void SetFocus<T>(this ViewModel vm, Expression<Func<T>> propertyLambda)
{
var me = propertyLambda.Body as MemberExpression;
SetFocus(vm, me.Member.Name);
}
/// <summary>
/// Sets the focus to the visual element that binds to the specified property.
/// </summary>
/// <param name="vm">The view model.</param>
/// <param name="propertyName">The property name.</param>
public static void SetFocus(this ViewModel vm, string propertyName)
{
Application.Current.Dispatcher.BeginInvoke(new Action(async () =>
{
await Task.Delay(200);
var control = GetUserControl(vm, Application.Current.MainWindow);
if (control != null)
{
var element = FindElementByPropertyName(vm, control, propertyName);
if (element != null)
{
element.Focusable = true;
Keyboard.Focus(element);
}
else
{
Debug.WriteLine($"SetFocus: {propertyName} not found!");
}
}
else
{
Debug.WriteLine($"SetFocus: {propertyName} not found!");
}
}), DispatcherPriority.ApplicationIdle);
}
private static UserControl GetUserControl(ViewModel vm, FrameworkElement parent)
{
var children = parent.FindVisualChildren<UserControl>();
foreach (var child in children)
{
if (child.DataContext == vm)
{
return child;
}
else
{
var innerChild = GetUserControl(vm, child);
if (innerChild != null)
{
return innerChild;
}
}
}
return null;
}
private static FrameworkElement FindElementByPropertyName(ViewModel vm, FrameworkElement parent, string propName)
{
FrameworkElement foundChild = null;
var children = LogicalTreeHelper.GetChildren(parent).OfType<FrameworkElement>().ToList();
int count = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < count; i++)
{
var child = VisualTreeHelper.GetChild(parent, i) as FrameworkElement;
if (child != null)
{
children.Add(child);
}
}
children = children.Distinct().ToList();
foreach (var child in children)
{
if (child.DataContext == vm)
{
BindingExpression bindingExpression = child.GetBindingExpression(TextBox.TextProperty);
if (bindingExpression == null)
{
bindingExpression = child.GetBindingExpression(Button.CommandProperty);
}
if (bindingExpression == null)
{
bindingExpression = child.GetBindingExpression(Tango.SharedUI.Helpers.PasswordHelper.PasswordProperty);
}
if (bindingExpression == null)
{
bindingExpression = child.GetBindingExpression(AutoCompleteTextBox.SelectedItemProperty);
}
if (bindingExpression != null)
{
if (bindingExpression.ResolvedSourcePropertyName == propName)
{
return child;
}
}
}
foundChild = FindElementByPropertyName(vm, child, propName);
if (foundChild != null)
{
return foundChild;
}
}
return foundChild;
}
}
|