代码之家  ›  专栏  ›  技术社区  ›  Martien de Jong

奇怪的WPF绑定行为

  •  0
  • Martien de Jong  · 技术社区  · 5 年前

    当使用另一个绑定变量时,WPF中的用户控件绑定不起作用。 这是我的(简化)代码。

    我有这个WPF用户控件:

    XAML:

    <UserControl x:Class="WpfApplication.BindingTest"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 xmlns:local="clr-namespace:WpfApplication"
                 mc:Ignorable="d" 
                 d:DesignHeight="450" d:DesignWidth="800">
        <TextBlock Text="{Binding Test}" />
    </UserControl>
    

    C:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace WpfApplication
    {
        public partial class BindingTest
        {
            public static readonly DependencyProperty TestProperty =
                DependencyProperty.Register(
                    "Test", typeof(string),
                    typeof(BindingTest)
                );
    
            public string Test
            {
                get => (string)GetValue(TestProperty);
                set => SetValue(TestProperty, value);
            }
    
            public BindingTest()
            {
                InitializeComponent();
                DataContext = this;
            }
        }
    }
    

    主窗口 XAML:

    <Window x:Class="WpfApplication.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfApplication"
            mc:Ignorable="d"
            Title="MainWindow" Height="450" Width="800">
        <StackPanel>
            <local:BindingTest Test="{Binding hoi}" />
            <TextBlock Margin="5,0,0,0" Text="{Binding hoi}" />
            <local:BindingTest Test="XxX" />
            <TextBlock Margin="5,0,0,0" Text="XxX" />       
        </StackPanel>
    </Window>
    

    C:

    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using Kadaster.NewsLetters.DomainModel;
    
    namespace WpfApplication
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            public string hoi => "yYy";
    
            public MainWindow()
            {
                DataContext = this;
                InitializeComponent();
            }
        }
    }
    

    我期望的输出是:

    YYY YYXXXX XXX

    相反,我得到:

    YXY XXXXX

    我的bindingtest控件不打印YYY文本,而textBlock则打印。 知道这是为什么吗?

    2 回复  |  直到 5 年前
        1
  •  1
  •   Rekshino    5 年前

    tomeragon1在注释中指出它是正确的,您更改了 DataContext 用于用户控件。要解决此问题,您可以使用例如 RelativeSource .

    <local:BindingTest Test="{Binding DataContext.hoi, RelativeSource={RelativeSource AncestorType=local:MainWindow, Mode=FindAncestor}}"/>
    

    我不想硬编码A 数据上下文 :

    namespace WpfApplication
    {
        public partial class BindingTest
        {
            public static readonly DependencyProperty TestProperty =
                DependencyProperty.Register(
                    "Test", typeof(string),
                    typeof(BindingTest)
                );
    
            public string Test
            {
                get => (string)GetValue(TestProperty);
                set => SetValue(TestProperty, value);
            }
    
            public BindingTest()
            {
                InitializeComponent();
            }
        }
    }
    
    <UserControl x:Class="WpfApplication.BindingTest"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 xmlns:local="clr-namespace:WpfApplication"
                 mc:Ignorable="d" 
                 d:DesignHeight="450" d:DesignWidth="800">
        <TextBlock Text="{Binding Test, RelativeSource={RelativeSource AncestorType=local:BindingTest}}" />
    </UserControl>
    
        2
  •  1
  •   Dean Chalk    5 年前

    用户控件中的绑定表达式不正确,无法将DataContext设置为 在用户控件中。

    1)删除DataContext分配:

    public BindingTest()
    {
        InitializeComponent();
    }
    

    2)在用户控件XAML中,将绑定替换为:

    <TextBlock Text="{Binding RelativeSource={RelativeSource 
        Mode=FindAncestor, AncestorType=local:BindingTest}, 
        Path=Test}" />