gpt4 book ai didi

c# - 如果 TextBox 绑定(bind)了其 Content 属性,我如何访问 Label 对象?

转载 作者:太空宇宙 更新时间:2023-11-03 13:00:05 25 4
gpt4 key购买 nike

我的目标是在 LabelTextBox 内容无效时将 Label 的文本包含在错误消息中.在验证期间,当只有 TextBox 对象很容易获得时,我想获得对具有 Target 属性的 Label 对象的引用绑定(bind)到那个 TextBox

换句话说,给定绑定(bind)的,我想返回或检索该绑定(bind)的目标。 WPF BindingOperations.GetBindingExpression() 和相关方法要求目标对象已知。

在 WPF XAML 中我有这个:

<Label Target="{Binding ElementName=RatingTextBox}">_Rating:</Label>
<TextBox Name ="RatingTextBox"/>

在 C# 代码隐藏中我试过这个:

BindingExpression be = RatingTextBox.GetBindingExpression(TextBox.TextProperty);
string format = be.ParentBinding.StringFormat;

但是,上面的 be.ParentBinding 为 null,即使我的 TextBox 肯定受标签约束,因为热键“[Alt]-R”有效。我的 TextBox 能否以某种方式从 C# 代码隐藏中获取 Label 的文本?

最佳答案

如果我理解正确,您正在寻找一种方法来自动将 TextBoxTooltip 属性绑定(bind)到任何内容的 Content 属性Label 对象,TextBox 是其目标。

不幸的是,要最轻松地做到这一点,需要 WPF 中的一种机制,在给定绑定(bind)的 的情况下,识别其目标(或多个目标……单个源可以绑定(bind)到多个目标,类(class))。据我所知,不存在这样的机制。

但是,我至少可以想到几个不同的替代方案来实现类似的效果:

  1. 初始化窗口时,枚举所有 Label 对象以找到它们的目标,并相应地更新目标的 Tooltip 属性。要么明确设置它们,要么将属性绑定(bind)到 Label.Content 属性。
  2. 反转 Label 目标声明的方向。 IE。创建一个可以在 TextBox 对象上使用的附加属性,指示哪个 Label 应该以它为目标。然后使用此附加属性初始化适当的 Tooltip 属性(例如,在附加属性代码中,绑定(bind)或设置 Tooltip 属性,或者有一些其他属性也绑定(bind)到附加属性,当它发生变化时,处理那里的绑定(bind)或设置)。

在第二个选项中使用附加属性的动机是允许标签/目标关系在 XAML 中仍然只声明一次(即避免冗余)。只是声明出现在目标对象(即 TextBox)而不是标签对象中。

这里有几个例子可以说明我的意思……

上面的第一个选项:

XAML:

<Window x:Class="TestSO32576181BindingGivenSource.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:l="clr-namespace:TestSO32576181BindingGivenSource"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<StackPanel Orientation="Horizontal">
<Label x:Name="label1" Content="_Label:" Target="{Binding ElementName=textBox1}"/>
<TextBox x:Name="textBox1"/>
</StackPanel>
</StackPanel>
</Window>

C#:

public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();

InitTooltips(this);
}

private void InitTooltips(FrameworkElement element)
{
foreach (FrameworkElement child in
LogicalTreeHelper.GetChildren(element).OfType<FrameworkElement>())
{
Label label = child as Label;

if (label != null)
{
BindingExpression bindingExpression =
BindingOperations.GetBindingExpression(label, Label.TargetProperty);

if (bindingExpression != null)
{
TextBox textBox =
FindName(bindingExpression.ParentBinding.ElementName) as TextBox;

if (textBox != null)
{
// You could just set the value, as here:
//textBox.ToolTip = label.Content;

// Or actually bind the value, as here:
Binding binding = new Binding();

binding.Source = label;
binding.Path = new PropertyPath("Content");
binding.Mode = BindingMode.OneWay;

BindingOperations.SetBinding(
textBox, TextBox.ToolTipProperty, binding);
}
}
}

InitTooltips(child);
}
}
}


上面的第二个选项:

XAML:

<Window x:Class="TestSO32576181BindingGivenSource.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:l="clr-namespace:TestSO32576181BindingGivenSource"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<StackPanel Orientation="Horizontal">
<!-- Note that the Target property is _not_ bound in the Label element -->
<Label x:Name="label1" Content="_Label:"/>
<!-- Instead, it's specified here via the attached property: -->
<TextBox x:Name="textBox1" l:TooltipHelper.TargetOf="{Binding ElementName=label1}"/>
</StackPanel>
</StackPanel>
</Window>

C#:

static class TooltipHelper
{
public static readonly DependencyProperty TargetOfProperty =
DependencyProperty.RegisterAttached("TargetOf", typeof(Label),
typeof(TooltipHelper), new PropertyMetadata(null, _OnTargetOfChanged));

public static void SetTargetOf(FrameworkElement target, Label labelElement)
{
target.SetValue(TargetOfProperty, labelElement);
}

public static Label GetTargetof(FrameworkElement target)
{
return (Label)target.GetValue(TargetOfProperty);
}

private static void _OnTargetOfChanged(
DependencyObject target, DependencyPropertyChangedEventArgs e)
{
Label oldLabel = (Label)e.OldValue,
newLabel = (Label)e.NewValue;

if (oldLabel != null)
{
BindingOperations.ClearBinding(oldLabel, Label.TargetProperty);
BindingOperations.ClearBinding(target, FrameworkElement.ToolTipProperty);
}

if (newLabel != null)
{
Binding binding = new Binding();

binding.Source = newLabel;
binding.Path = new PropertyPath("Content");
binding.Mode = BindingMode.OneWay;

BindingOperations.SetBinding(
target, FrameworkElement.ToolTipProperty, binding);

binding = new Binding();
binding.Source = target;
binding.Mode = BindingMode.OneWay;

BindingOperations.SetBinding(
newLabel, Label.TargetProperty, binding);
}
}
}

请注意,在第二个选项中,窗口类中不需要新代码。它的构造函数可以像往常一样调用 InitializeComponent() 就可以了。所有代码隐藏都在 TooltipHelper 类中结束,该类在 XAML 本身中被引用。

关于c# - 如果 TextBox 绑定(bind)了其 Content 属性,我如何访问 Label 对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32576181/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com