简体   繁体   中英

Get XAML controls by their bound properties?

Is there a way to get the controls in XAML using the properties bound to them,

something like this:

 Account acc = GetFromDB(id);
 foreach (var prop in acc.GetType().GetProperties())
 {
      Control control = GetControl(prop.Name);
      //Then I want to set properties like Foreground for the control
 }

 private Control GetControl(string propertyName)
 {
      //getting the control bound to the propertyName
 }

and say that this is XAML code:

            <Label>Name</Label>
            <TextBox Name="txtName" 
                     Grid.Column="1" 
                     Text="{Binding Name}"/>
            <Label Grid.Row="1">Debt</Label>
            <TextBox Name="txtDebt" 
                     Grid.Column="1" 
                     Grid.Row="1" 
                     Text="{Binding Debt}"/>
            <Label Grid.Row="2">Join Date</Label>
            <DatePicker Name="dpJoin" 
                        Grid.Column="1" 
                        Grid.Row="2" 
                        Text="{Binding JDate}"/>

Just set x:Name and find control you need by VisualTreeHelper . If you need a specific control name, you can bind it like x:Name="{Binding Name}"

public static T GetChildOfType<T>(this 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;
}

And here is a sample ho do it by property name:

public static T FindVisualChildByName<T>(FrameworkElement depObj, string name) where T : FrameworkElement
    {
        if (depObj != null)
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
            {
                var child = VisualTreeHelper.GetChild(depObj, i) as FrameworkElement;
                if (child != null && child is T && child.Name == name)
                    return (T)child;

                T childItem = FindVisualChildByName<T>(child, name);
                if (childItem != null)
                    return childItem;
            }
        }
        return null;
    }

EDIT:

There is example how to use this methods.

FindVisualChildByName<T> method have two parameters, first is the page or control instance where you will seeking for, and second is control name to find on the page.

Not sure how to get Frame or page instance in WPF, but in UWP it looks like this:

var frame = Window.Current.Content as Frame;
var textBox = VisualHelper.GetChildOfType<TextBox>(frame);
var anotherTextBox = VisualHelper.FindVisualChildByName<TextBox>(frame, "MyTextBox");

Or cast like this:

var obj = VisualHelper.FindVisualChildByName<object>(frame, "MyTextBox");
var type = obj.GetType();
var textBox = System.Convert.ChangeType(obj, type);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM