【问题标题】:Get XAML controls by their bound properties?通过绑定属性获取 XAML 控件?
【发布时间】:2018-01-03 02:29:22
【问题描述】:

有没有办法使用绑定到它们的属性来获取 XAML 中的控件,

类似这样的:

 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
 }

并说这是 XAML 代码:

            <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}"/>

【问题讨论】:

  • 在控件上设置名称属性,如&lt;TextBox x:Name="myTextBox" /&gt;,现在您可以在代码中使用此名称访问此控件,如myTextBox.Width = 300;
  • 我在上面的代码中设置了,现在跳过那个解决方案!
  • 这正是我想要的:stackoverflow.com/a/35695596/6197785

标签: c# wpf xaml


【解决方案1】:

只需设置x:Name 并通过VisualTreeHelper 找到您需要的控制。 如果需要特定的控件名,可以像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;
}

这是一个示例,按属性名称进行操作:

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;
    }

编辑:

有示例如何使用此方法。

FindVisualChildByName&lt;T&gt; 方法有两个参数,第一个是您要查找的页面或控件实例,第二个是要在页面上查找的控件名称。

不确定如何在 WPF 中获取 Frame 或页面实例,但在 UWP 中它看起来像这样:

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

或者像这样投射:

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

【讨论】:

  • 你能解释一下你的代码吗,我期望的是一个只接受一个字符串值(即属性名称)并返回绑定到该属性的控件的方法
  • 查看问题的编辑
  • 但是控件可能是TextBoxCheckBoxDatePicker..等等。我只是不知道属性和它的绑定控件!
  • 这里是完整的sample
  • 你可以尝试通过System.Convert.ChangeType(obj, type);进行控制,再次查看编辑
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-22
  • 2012-09-01
  • 2015-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多