【问题标题】:Can a XAML object be a source for one binding as well as a target for another binding?XAML 对象能否作为一个绑定的源以及另一个绑定的目标?
【发布时间】:2011-01-07 11:51:50
【问题描述】:

是否可以将 TextBlock 作为目标和源?

基本上我有一堆与其他实体有简单关系的实体(如 Entity1 Knows Entity3、Entity3 WorksAt Entity2 等)

我有一个 Link 类,用于存储 SourceEntityRelationshipTargetEntity 详细信息。

我想要做的是选择一个实体,然后显示与该实体相关的关系,每个关系的目标实体都列在关系名称下方。

选择实体后,ObservableCollection 将填充该特定实体的 Links (SelectedEntityLinks<Link>)。

因为每个实体可能与多个目标实体具有相同的关系(例如,Entity1 可以知道 Entity3 和 Entity4),所以我创建了一个方法 GetThisRelationshipEntities(),它以关系名称作为参数,查看SelectedEntityLinks 用于匹配参数的关系名称,并返回带有该关系目标实体的ObservableCollection

在我的 xaml 中,我有一个 WrapPanel 在 TextBlock 中显示每个关系名称:

<TextBlock x:Name="relationship" Text="{Binding Path=Relationship.Name}" />

然后在另一个文本块下面,它应该显示GetThisRelationshipEntities(String relationshipName). 的结果

所以我希望“关系”TextBlock 既可以从我上面显示的绑定中获取其文本,也可以将其文本作为参数提供给我已添加到&lt;UserControl.Resources&gt;GetThisRelationshipEntities() 方法一个 ObjectDataProvider。

对不起,如果这有点罗嗦,但我希望它很清楚。任何指针/建议都会很棒。

【问题讨论】:

    标签: wpf xaml binding


    【解决方案1】:

    对我来说,听起来您应该使用 IValueConverter 创建一个值转换器类和一个属性,即关系表。 做的时候

    <TextBlock x:Name="relationship" Text="{Binding Path=Relationship.Name}" />
    

    你会添加

    <TextBlock x:Name="relationship" Text="{Binding Path=Relationship.Name, Converter={StaticResource myRelationConverter}}" />
    

    Convert() 方法中,你可以做任何你想做的疯狂的事情。

    【讨论】:

    • 谢谢马丁,我会研究价值转换器。但是有一个问题,如果我使用一种称为 Convert() 的方法,我如何将来自 TextBlock 的 Relationship.Name 传递给它?还是使用 Converter={StaticResource myRelationConverter} 会做什么? TextBlock 当前显示的 Relationship.Name 是显示正确数据的关键。如果我能弄清楚如何找回它!
    • 转换器作为绑定操作的一部分被调用。 1. 检索Relationship.Name 的值 2. 框架将值传递给给定的值转换器convert 方法3. Convert 方法的返回值写入Text 属性
    【解决方案2】:

    我不完全确定我得到了你想要做什么,但我建议尝试将绑定模式设置为 TwoWay。

    <TextBlock x:Name="relationship" Text="{Binding Path=Relationship.Name}"
                 Mode=TwoWay />
    

    虽然现在我想了想,它可能是默认选项,所以你也可以尝试在 TextBlock 上调用 GetThisRelationshipEntities() 函数,每次更新它的源时:

    private void relationship_SourceUpdated(object sender, DataTransferEventArgs e)
    {
        //To DO: whatever update you wanna make
    }
    

    【讨论】:

    • 感谢 Notter,但据我了解,TwoWay 绑定仅适用于一个目标及其源之间。我需要“关系”TextBlock 来使用特定的源(Relationship.Name)来设置其 Text 值,然后一旦设置了值,就可以将其提供给不同的目标(使用类似 Text="{Binding Path = MethodParameters[ 0]"..../>).
    • 嗯,我现在有点困惑,但我认为我建议在 SourceUpdated 事件上更新不同的目标将是最简单的方法
    • 嗯,我尝试过使用 SourceUpdated,但没有运气。我认为问题在于我的源是一个 ObservableCollection 并且我的名为“relationship”的 TextBlock 只是一个接一个地显示 Relationship.Names (它在一个包装面板中,所以它在我指定的模板中一个接一个地显示它们。)所以源实际上并没有被更新,它只是 TextBlock 中的 Text 值发生了变化。我也尝试使用 TargetUpdated,但也没有运气:(
    【解决方案3】:

    您的措辞有点不准确:不是DependencyObjects 是绑定的源或目标,而是DependencyObjects属性。普通属性只能作为绑定中的源,但DependencyProperty 既可以作为源也可以作为目标。例如在

    <TextBox Text="{Binding Path=Name}" Name="txtName" />
    <Label Content="{Binding ElementName=txtName, Path=Text}" />
    

    TextBoxText属性是绑定到DataContext中的一些Name属性的目标,同时也是绑定到Content属性的源Label。方法调用的参数不是属性,因此它不能是绑定中的源或目标。在您的情况下,最简单的解决方案可能是处理 TextBlock.TextChanged 事件并从那里调用您的方法。使用 Martin 建议的 ValueConverter 也是一种选择。

    编辑:这是一个工作示例,演示了使用TextChanged 事件的方法。每次您更改某些内容时,它都会将TextBox 的内容写入Console。要绑定到方法的结果,您可以让事件处理程序将其结果写入属性,然后绑定到该属性。

    MainWindow.xaml:

    <Window x:Class="WpfApplication1.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <StackPanel Orientation="Vertical">
            <TextBox Name="textBox1" TextChanged="textBox1_TextChanged" />
        </StackPanel>
    </Window>
    

    MainWindow.xaml.cs:

    using System;
    using System.Windows;
    using System.Windows.Controls;
    
    namespace WpfApplication1
    {
      /// <summary>
      /// Interaction logic for MainWindow.xaml
      /// </summary>
      public partial class MainWindow : Window
      {
        public MainWindow()
        {
          InitializeComponent();
        }
    
        private void textBox1_TextChanged(object sender, TextChangedEventArgs e)
        {
            Console.WriteLine(this.textBox1.Text);
        }
      }
    }
    

    【讨论】:

    • 感谢您的解释。我尝试使用 TextBox.TextChanged 事件(因为找不到 TextBlock 的 TextChanged 事件),但是当文本更改时它不会触发。我仍在尝试将 Value Converters 作为一个选项,但我的 Convert 类在每次调用时都会引发异常。至少我在尝试解决这个问题的过程中学到了很多关于 WPF 的知识......!我了解它是绑定的 DependencyObjects 的属性,但我遇到困难的地方是尝试使用此页面上概述的过程msdn.microsoft.com/en-us/library/aa348824.aspx
    • 我已将方法 GetThisRelationshipEntities(String relationshipName) 添加为 UserControl 资源,但为了将 DependencyObject 的属性绑定到方法的结果,我当然必须将字符串值传递给方法。但是要使用 TextBlock.Text 值作为参数,看起来您必须执行类似 之类的操作
    • 这就是我的 TextBlock.Text 属性需要既是目标又是源的意思,因为它是 Text="{Binding Path=Relationship.Name" 的目标,但也是“源”为方法参数。但是,我会继续尝试您建议的不同方法,如果我成功了,我会告诉您。为所有的 cmets 道歉,但我无法一口气发布所有内容!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-20
    • 1970-01-01
    • 2015-09-25
    相关资源
    最近更新 更多