c# - 绑定(bind)导致 StackOverflow

标签 c# wpf xaml binding

我不确定我在这里做错了什么。

比方说,我有两个 UserControls BoxABoxB。两者都有一个名为 Text

的 DependencyProperty

BoxB 包装了具有常规 TextBox 的 BoxA。

绑定(bind)应该像这样 BoxB.Text <=> BoxA.Text <=> TextBox.Text

Xaml BoxA:

<UserControl x:Class="SandBoxWpf.BoxA"
             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"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300"
             DataContext="{Binding RelativeSource={RelativeSource Self}}">

    <TextBox Text="{Binding Text, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"></TextBox>

</UserControl>

Xaml BoxB:

<UserControl x:Class="SandBoxWpf.BoxB"
             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:SandBoxWpf"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300"
             DataContext="{Binding RelativeSource={RelativeSource Self}}">

    <local:BoxA Text="{Binding Text, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"></local:BoxA>

</UserControl>

BoxA 和 BoxB 的代码隐藏

using System.Windows;
using System.Windows.Controls;

namespace SandBoxWpf
{
    /// <summary>
    /// Interaktionslogik für BoxA.xaml
    /// </summary>
    public partial class BoxX : UserControl
    {
        public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
                "Text",
                typeof(string),
                typeof(BoxX),
                new PropertyMetadata(default(string)));

        public string Text
        {
            get => (string) GetValue(TextProperty);
            set => SetValue(TextProperty, value);
        }

        public BoxX()
        {
            InitializeComponent();
        }
    }
}

主窗口

<Window x:Class="SandBoxWpf.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:SandBoxWpf"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525"
        DataContext="{Binding RelativeSource={RelativeSource Self}}">
    <Grid>
        <local:BoxB Width="100" Height="20" Text="{Binding Title}"></local:BoxB>
    </Grid>
</Window>

只要我在 BoxB 中输入一些内容,我就会收到 StackoverflowException。 如果我删除 Mode=TwoWay 或 UpdateSourceTrigger,StackOverflow 就会消失,但绑定(bind)也不起作用。

最佳答案

如果您正在构建具有可绑定(bind)属性(即依赖属性)的 UserControl,则您必须在任何情况下都必须显式设置 UserControl 的 DataContext,无论是对控件实例还是对任何私有(private) View 模型。

如果你这样做,一个类似于

的绑定(bind)
<local:BoxB Text="{Binding Title}">

将不再起作用。该 Binding 需要当前 DataContext 中的对象具有 Title 属性。 DataContext 属性值通常继承自 UserControl 的父元素,例如 window 。但是,由于您已显式设置 DataContext,因此可以避免这种机制。

这与 UserControls 中的同名属性尤其令人困惑。当你写的时候

<local:BoxA Text="{Binding Text, ...}"/>

在 UserControl BoxB 中,您期望绑定(bind)源属性为 BoxB.Text。事实上它是 BoxA.Text,因为 BoxA 的 DataContext 是 BoxA 实例。


所以删除任何

DataContext="{Binding RelativeSource={RelativeSource Self}}"

行并使用RelativeSource 在 UserControl 的 XAML 中编写绑定(bind),如下所示:

<TextBox Text="{Binding Text, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay},
                RelativeSource={RelativeSource AncestorType=UserControl}"/>

<local:BoxA Text="{Binding Text, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay},
                   RelativeSource={RelativeSource AncestorType=UserControl}"/>

关于c# - 绑定(bind)导致 StackOverflow,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48707331/

相关文章:

c# - Rabin-Karp 算法用于使用滚动哈希实现抄袭

wpf - 在 Canvas 上定位 UIElement

wpf - 在设计时使用抽象基类呈现用户控件

WPF 数据网格 : The selected row is not properly highlighted when using HorizontalAlignment

silverlight - XAML到HTML转换器

c# - 在 blazor web 程序集中,每秒调用 StateHasChanged() 是最佳选择吗?

c# - 从轮廓生成HALCON区域

c# - JsonPropertyAttribute 在派生类中的私有(private)属性上被忽略

wpf - .net 4 wpf 功能区中的 Windows 8 native 外观

c# - 在单个 WPF 控件中列出所有 Validation.Errors?