加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 如何在没有Name或x:Name的情况下绑定到控件?

发布时间:2020-12-15 05:40:58 所属栏目:百科 来源:网络整理
导读:是的,所以我正在关注一个教程. This one,确切地说.它提供的一些代码是这样的: TextBlock Margin="2" Foreground="Red" FontWeight="Bold" Text="{Binding ElementName=AddressBox,Path=(Validation.Errors),Converter={StaticResource eToMConverter}}" /
是的,所以我正在关注一个教程. This one,确切地说.它提供的一些代码是这样的:
<TextBlock Margin="2" Foreground="Red" FontWeight="Bold" 
           Text="{Binding ElementName=AddressBox,Path=(Validation.Errors),Converter={StaticResource eToMConverter}}" />

如您所见,它绑定到TextBox的验证错误,TextBox的x:Name是AddressBox.现在,我的问题是:我有一个像这样的窗口.它也只有一个TextBox.但是,如果可能的话,我宁愿不使用Names或x:Names.是否可以绑定到另一个Control的Validation.Errors而不是该控件被命名,并且该控件是同一个窗口中该控件类型中唯一的一个? TextBox与ListBox位于同一级别.

解决方法

除了与ElementName绑定之外的其他方式是使用 x:Reference,但它还需要目标元素在其上定义x:Name.所以,这超出了范围.

在没有定义名称的情况下我可以想到的其他方法是绑定类似下面的内容(绑定到父级和索引器以获取目标子级).

但这与您的逻辑树结构紧密耦合 –

<StackPanel>
        <TextBlock Text="Test"/>
        <TextBlock Text="{Binding Parent.Children[0].Text,RelativeSource={RelativeSource Mode=Self}}"/>
    </StackPanel>

此外,这可以使用IValueConverter来实现.正如您所提到的,在父容器中只有一个这种类型的元素,您可以将父级传递给转换器,转换器将使用VisualTreeHelper类遍历子级.

<StackPanel>
        <TextBlock Text="Test"/>
        <TextBlock Text="{Binding Parent,RelativeSource={RelativeSource Self},Converter={StaticResource MyConverter}}"/>
     </StackPanel>

这是您的转换器代码 –

public class MyConverter: IValueConverter
{
    public object Convert(object value,Type targetType,object parameter,System.Globalization.CultureInfo culture)
    {
        if (value is DependencyObject) 
        {
            var textBlock = FindChild<TextBlock>((DependencyObject)value,null);
            return (textBlock == null)?string.Empty:textBlock.Text;
        }
        else
            return String.Empty;
    }

    public object ConvertBack(object value,System.Globalization.CultureInfo culture)
    {
        return Binding.DoNothing;
    }
}

这是使用VisualTreeHelper遍历的方法.我把这个方法放在我的Utility类中,在很多情况下都很方便 –

public static T FindChild<T>(DependencyObject parent,string childName)
       where T : DependencyObject
    {
        // Confirm parent is valid.  
        if (parent == null) return null;

        T foundChild = null;

        int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
        for (int i = 0; i < childrenCount; i++)
        {
            var child = VisualTreeHelper.GetChild(parent,i);
            // If the child is not of the request child type child 
            T childType = child as T;
            if (childType == null)
            {
                // recursively drill down the tree 
                foundChild = FindChild<T>(child,childName);

                // If the child is found,break so we do not
                // overwrite the found child.  
                if (foundChild != null) break;
            }
            else if (!string.IsNullOrEmpty(childName))
            {
                var frameworkElement = child as FrameworkElement;
                // If the child's name is set for search 
                if (frameworkElement != null
                    && frameworkElement.Name == childName)
                {
                    // if the child's name is of the request name 
                    foundChild = (T)child;
                    break;
                }
            }
            else
            {
                // child element found. 
                foundChild = (T)child;
                break;
            }
        }

        return foundChild;
    }

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读