绑定值未传递给 WPF 中的用户控件

2024-04-12

我仔细观察了很久,却被困住了。我试图通过 Window 的绑定将参数从 Window 传递到 UserControl1。

在 MainWindow 中,UserControl1 被包含两次,一次通过 MyValue 上的绑定传递参数 MyCustom,再次使用文字。传递绑定对 UserControl1 没有影响。 MyCustom 依赖属性未更改。按照字面意思,它会按预期工作。

我很困惑。我已将示例复制到https://stackoverflow.com/a/21718694/468523 https://stackoverflow.com/a/21718694/468523但没有喜悦。我一定缺少一些简单的东西。

对我复制的所有代码感到抱歉,但问题往往在于细节..

主窗口.xaml

<Window x:Class="MyParamaterizedTest3.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:MyParamaterizedTest3"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525"
        DataContext="{Binding RelativeSource={RelativeSource Self}}">
    <Grid HorizontalAlignment="Center" VerticalAlignment="Center">
        <StackPanel>
            <Rectangle Height="20"/>
            <local:UserControl1 MyCustom="{Binding MyValue, UpdateSourceTrigger=PropertyChanged}"/>
            <Rectangle Height="20"/>
            <local:UserControl1 MyCustom="Literal Stuff"/>
            <Rectangle Height="20"/>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="MainWindow: "/>
                <TextBlock Text="{Binding MyValue, UpdateSourceTrigger=PropertyChanged}"/>
            </StackPanel>
        </StackPanel>
    </Grid>
</Window>

MainWindow.xaml.cs

namespace MyParamaterizedTest3
{
    public partial class MainWindow : INotifyPropertyChanged
    {
        public MainWindow()
        {
            InitializeComponent();
        }
        public string MyValue { get => _myValue; set => SetField(ref _myValue, value); }
        private string _myValue= "First things first";
        public event PropertyChangedEventHandler PropertyChanged;
        protected bool SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
        {
            if (EqualityComparer<T>.Default.Equals(field, value)) { return false; }
            field = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            return true;
        }
    }
}

UserControl1.xaml(在下面更正)

<UserControl x:Class="MyParamaterizedTest3.UserControl1"
             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:MyParamaterizedTest3"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300"
             DataContext="{Binding RelativeSource={RelativeSource Self}}"
             >
    <Grid HorizontalAlignment="Center" VerticalAlignment="Center">
          <Border BorderThickness="3" BorderBrush="Black">
              <StackPanel>
                  <TextBlock Text="{Binding MyCustom, UpdateSourceTrigger=PropertyChanged, FallbackValue=mycustom}"></TextBlock>
              </StackPanel>
          </Border>  
    </Grid>
</UserControl>

UserControl1.xaml.cs(在下面更正)

namespace MyParamaterizedTest3
{
    public partial class UserControl1 : INotifyPropertyChanged
    {
        public UserControl1()
        {
            InitializeComponent();
        }
        public static readonly DependencyProperty MyCustomProperty =
            DependencyProperty.Register("MyCustom", typeof(string), typeof(UserControl1));
        public string MyCustom
        {
            get
            {
                return this.GetValue(MyCustomProperty) as string;
            }
            set
            {
                this.SetValue(MyCustomProperty, value);
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;
        protected bool SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
        {
            if (EqualityComparer<T>.Default.Equals(field, value)) { return false; }
            field = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            return true;
        }
    }
}

更正了 UserControl1.xaml(根据 Ed Plunkett)

<UserControl x:Class="MyParamaterizedTest3.UserControl1"
             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"
             >
    <Grid HorizontalAlignment="Center" VerticalAlignment="Center">
          <Border BorderThickness="3" BorderBrush="Black">
              <StackPanel>
                <TextBlock Text="{Binding MyCustom, RelativeSource={RelativeSource AncestorType=UserControl}, FallbackValue=mycustom}"></TextBlock>
              </StackPanel>
          </Border>  
    </Grid>
</UserControl>

更正了 UserControl1.xaml.cs(根据 Ed Plunkett)

<UserControl x:Class="MyParamaterizedTest3.UserControl1"
             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"
             >
    <Grid HorizontalAlignment="Center" VerticalAlignment="Center">
          <Border BorderThickness="3" BorderBrush="Black">
              <StackPanel>
                <TextBlock Text="{Binding MyCustom, RelativeSource={RelativeSource AncestorType=UserControl}, FallbackValue=mycustom}"></TextBlock>
              </StackPanel>
          </Border>  
    </Grid>
</UserControl>

在窗口 XAML 中,默认情况下,用户控件实例上的绑定使用用户控件的 DataContext 作为其源。您假设它从窗口继承其数据上下文。

但这是用户控件中的:

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

这打破了父母给它的所有绑定。所以不要这样做。使用相对来源:

<UserControl x:Class="MyParamaterizedTest3.UserControl1"
             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:MyParamaterizedTest3"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300"
             >
    <Grid HorizontalAlignment="Center" VerticalAlignment="Center">
          <Border BorderThickness="3" BorderBrush="Black">
              <StackPanel>
                  <TextBlock Text="{Binding MyCustom, RelativeSource={RelativeSource AncestorType=UserControl}, FallbackValue=mycustom}"></TextBlock>
              </StackPanel>
          </Border>  
    </Grid>
</UserControl>

Also:

  1. UpdateSourceTrigger=PropertyChanged对于绑定到从不更新其源的属性没有任何作用,因此可以省略。

  2. 正如我们在评论中讨论的那样,INotifyPropertyChanged依赖属性不需要。

  3. 当绑定不起作用时,这是非常令人沮丧的,因为如何调试它们?你什么也看不见。关键的是它在哪里寻找该房产?您可以获得如下诊断信息:

    <TextBlock 
        Text="{Binding MyCustom, PresentationTraceSources.TraceLevel=High, FallbackValue=mycustom}"></TextBlock>
    

    这将在运行时向 Visual Studio 的输出窗格发出大量调试信息。它将详细告诉您 Binding 正在尝试执行什么操作、它发现了什么以及哪里失败。

  4. 该窗口可以将其自己的 DataContext 设置为 Self,因为它没有父级,因此它不会踩在继承的 DataContext 上。然而,窗口可以而且应该使用RelativeSource本身——或者更好的是,编写一个主视图模型类(你已经知道如何实现INPC),将窗口的属性移动到主视图模型,并将视图模型的实例分配给窗口的视图模型。数据上下文。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

绑定值未传递给 WPF 中的用户控件 的相关文章

  • 为什么基类必须有一个带有 0 个参数的构造函数?

    这不会编译 namespace Constructor0Args class Base public Base int x class Derived Base class Program static void Main string a
  • 获取两个字符串之间的公共部分c# [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我需要的是获取两个单词之间的共同部分并获取差异 例子 场景1 word1 感言 word2 Test 将返回 公共部分Test 不同之
  • 通信对象 System.ServiceModel.Channels.ServiceChannel 不能用于通信

    通信对象System ServiceModel Channels ServiceChannel 无法用于通信 因为它处于故障状态 这个错误到底是什么意思 我该如何解决它 您收到此错误是因为您让服务器端发生 NET 异常 并且您没有捕获并处理
  • 在 C++11 中省略返回类型

    我最近发现自己在 C 11 模式下的 gcc 4 5 中使用了以下宏 define RETURN x gt decltype x return x 并编写这样的函数 template
  • try-catch 中未处理的异常

    try list from XElement e in d Descendants wix File where e Attribute Name Value Contains temp Name e Parent Parent Attri
  • 在 Xcode4 中使用 Boost

    有人设置 C Xcode4 项目来使用 Boost 吗 对于一个简单的 C 控制台应用程序 我需要在 Xcode 中设置哪些设置 Thanks 用这个来管理它 和这个
  • std::map 和二叉搜索树

    我读过 std map 是使用二叉搜索树数据结构实现的 BST 是一种顺序数据结构 类似于数组中的元素 它将元素存储在 BST 节点中并按其顺序维护元素 例如如果元素小于节点 则将其存储在节点的左侧 如果元素大于节点 则将其存储在节点的右侧
  • C++11 函数局部静态 const 对象的线程安全初始化

    这个问题已在 C 98 上下文中提出 并在该上下文中得到回答 但没有明确说明有关 C 11 的内容 const some type create const thingy lock my lock some mutex static con
  • 转到 C# WPF 中的第一页

    我正在 WPF 中使用导航服务 为了导航到页面 我使用 this NavigationService Navigate new MyPage 为了返回我使用 this NavigationService GoBack 但是如何在不使用的情况
  • 是否有与 C++11 emplace/emplace_back 函数类似的 C# 函数?

    从 C 11 开始 可以写类似的东西 include
  • Xamarin Android:获取内存中的所有进程

    有没有办法读取所有进程 而不仅仅是正在运行的进程 如果我对 Android 的理解正确的话 一次只有一个进程在运行 其他所有进程都被冻结 后台进程被忽略 您可以使用以下代码片段获取当前正在运行的所有 Android 应用程序进程 Activ
  • C# 编译器如何决定发出可重定向的程序集引用?

    NET Compact Framework 引入了可重定向程序集引用 现在用于支持可移植类库 基本上 编译器会发出以下 MSIL assembly extern retargetable mscorlib publickeytoken 7C
  • gdb查找行号的内存地址

    假设我已将 gdb 附加到一个进程 并且在其内存布局中有一个文件和行号 我想要其内存地址 如何获取文件x中第n行的内存地址 这是在 Linux x86 上 gdb info line test c 56 Line 56 of test c
  • 运行代码首先迁移更新数据库时出错

    我在迁移到数据库时遇到问题 并且似乎找不到我遇到的错误的答案 System MissingMethodException Method not found System Data Entity Migrations Builders Tab
  • 我应该在应用程序退出之前运行 Dispose 吗?

    我应该在应用程序退出之前运行 Dispose 吗 例如 我创建了许多对象 其中一些对象具有事件订阅 var myObject new MyClass myObject OnEvent OnEventHandle 例如 在我的工作中 我应该使
  • 以编程方式使用自定义元素创建网格

    我正在尝试以编程方式创建一个网格 并将自定义控件作为子项附加到网格中 作为 2x2 矩阵中的第 0 行第 0 列 为了让事情变得更棘手 我使用了 MVVM 设计模式 下面是一些代码可以帮助大家理解这个想法 应用程序 xaml cs base
  • 热重载时调用方法

    我正在使用 Visual Studio 2022 和 C 制作游戏 我想知道当您热重新加载应用程序 当它正在运行时 时是否可以触发一些代码 我基本上有 2 个名为 UnloadLevel 和 LoadLevel 的方法 我想在热重载时执行它
  • Swagger 为 ASP.CORE 3 中的字典生成错误的 URL

    当从查询字符串中提取的模型将字典作为其属性之一时 Swagger 会生成不正确的 URL 如何告诉 Swagger 更改 URL 中字典的格式或手动定义输入参数模式而不自动生成 尝试使用 Swashbuckle 和 NSwag 控制器 pu
  • Azure函数版本2.0-应用程序blobTrigger不工作

    我有一个工作功能应用程序 它有一个 blob 输入和一个事件中心输出 在测试版中工作 随着最新的更改 我的功能不再起作用 我尝试根据发行说明更新 host json 文件 但它没有引用 blob 触发器 version 2 0 extens
  • 如何确定母版页中正在显示哪个子页?

    我正在母版页上编写代码 我需要知道正在显示哪个子 内容 页面 我怎样才能以编程方式做到这一点 我用这个 string pageName this ContentPlaceHolder1 Page GetType FullName 它以 AS

随机推荐