aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/FSE/Tango.FSE.Common/ExtensionMethods/ViewModelExtensionMethods.cs
blob: 73ecd990bfb0e1e8139c35819084d042f805b339 (plain)
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
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(() =>
        {
            var element = FindElementByPropertyName(vm, Application.Current.MainWindow, propertyName);

            if (element != null)
            {
                element.Focusable = true;
                Keyboard.Focus(element);
            }
            else
            {
                Debug.WriteLine($"SetFocus: {propertyName} not found!");
            }

        }), DispatcherPriority.ApplicationIdle);
    }

    private static FrameworkElement FindElementByPropertyName(ViewModel vm, UIElement 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;
    }
}