.NET 3.5 和 .NET 4.5 之间的多重绑定发生了什么?

2024-06-21

我们目前正在将项目从 .NET 版本 3.5 转换为版本 4.5。

我们使用多重绑定转换器设置了一个文本框 IsEnabled 标记。每个绑定都有自己的转换器。

所有这些在 .NET 3.5 中都运行良好,但在 .NET 4.5 中,传递给子转换器的目标类型是 object 类型而不是 bool 类型。

这是一个已知的问题? MS 是否重构了多重绑定,以不将目标类型传递给子转换器。

我创建了一个简化的项目来演示该问题。我在 VS2008 中创建了该项目,然后将其转换为 VS2012 和 .NET 4.5。

窗口 XAML:

<Window x:Class="TestMultiBinding.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:TestMultiBinding"        
    Title="Window1" Height="300" Width="300">
    <Window.Resources>
        <local:NotConverter x:Key="NotConverter"/>
        <local:MultiBoolConverter x:Key="MultiBoolConverter"/>
    </Window.Resources>
    <StackPanel>

        <TextBox>
            <TextBox.IsEnabled>
                <MultiBinding Converter="{StaticResource MultiBoolConverter}">
                    <Binding Path="ConditionOne" />
                    <Binding Path="ConditionTwo" Converter="{StaticResource NotConverter}"/>
                </MultiBinding>
            </TextBox.IsEnabled>
        </TextBox>


    </StackPanel>
</Window>

c#:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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 System.Globalization;

namespace TestMultiBinding
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
            DataContext = new ViewModel();
        }
    }

    public class ViewModel
    {
        public bool ConditionOne { get { return true; } }
        public bool ConditionTwo { get { return false; } }
    }

    /// <summary>
    /// Converts a boolean to its inverse (useful for radio buttons).
    /// </summary>
    [ValueConversion(typeof(bool), typeof(bool))]
    public class NotConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (targetType != typeof(bool) && targetType != typeof(bool?)) { throw new ArgumentException("Can only convert booleans.", "targetType"); }

            //return !(bool)value;
            return !true.Equals(value);
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return Convert(value, targetType, parameter, culture);
        }
    }

    /// <summary>
    /// Converts multiple boolean values to one. Uses AND by default. Possible extension: Pass the desired operation as parameter
    /// </summary>
    [ValueConversion(typeof(bool), typeof(bool))]
    public class MultiBoolConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            try
            {
                // todo: support other operations like OR, XOR
                return values.Cast<bool>().Aggregate(true, (res, cur) => res && cur);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Trace.TraceError("MultiBoolConverter({0}): {1}", parameter, ex.Message);
                return DependencyProperty.UnsetValue;
            }
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            System.Diagnostics.Trace.TraceError("MultiBoolConverter: does not support TwoWay or OneWayToSource bindings.");
            return null;
        }
    }

}

您测试 targetType 为 bool 是否有原因?

我很惊讶它在 3.5 中起作用,因为 NonConverter 正在从 bool 转换为对象(因为 MultiBinding 将对象数组作为输入输出)。


我使用反射器进行了一些挖掘,底层逻辑确实发生了变化。

这是来自internal void TransferValue(object newValue, bool isASubPropertyChange)的方法BindingExpression

In 3.5:

internal void TransferValue(object newValue, bool isASubPropertyChange)
{
  DependencyObject targetElement = this.TargetElement;
  if (targetElement == null || this.Worker == null)
    return;
  Type propertyType = this.TargetProperty.PropertyType;

在 4.5 中,所有调用propertyType被以下定义替换effectiveTargetType:

internal void TransferValue(object newValue, bool isASubPropertyChange)
{
  DependencyObject targetElement = this.TargetElement;
  if (targetElement == null || this.Worker == null)
    return;
  Type effectiveTargetType = this.GetEffectiveTargetType();
...
}

internal Type GetEffectiveTargetType()
{
  Type type = this.TargetProperty.PropertyType;
  for (BindingExpressionBase bindingExpressionBase = this.ParentBindingExpressionBase; bindingExpressionBase != null; bindingExpressionBase = bindingExpressionBase.ParentBindingExpressionBase)
  {
    if (bindingExpressionBase is MultiBindingExpression)
    {
      type = typeof (object);
      break;
    }
  }
  return type;
}

我不确定在这种情况下 TargetProperty 设置为什么,但您可以看到为什么它现在被设置为 MultiBindings 的对象。

而且,仅供参考,此更改似乎发生在 .NET 4.0 中。

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

.NET 3.5 和 .NET 4.5 之间的多重绑定发生了什么? 的相关文章

  • 使用 WPF 数据绑定将 NULL 值显示为“NULL”的最简单方法是什么?

    我有一个遗留数据库 我正在使用 Linq to Sql 为其构建自定义查看器 现在表中的某些字段可以具有 NULL 值 在 DataTemplate 中使用普通数据绑定 为 ORM 设计器生成的类键入
  • 如何以编程方式将焦点设置到已获得焦点的 WPF ListBox 中的 SelectedItem?

    我们想要设置SelectedItem of a ListBox以编程方式并希望该项目获得焦点 以便箭头键相对于该选定项目起作用 看起来很简单 然而问题是如果ListBox设置时已经有键盘焦点SelectedItem以编程方式 虽然它确实正确
  • MVVM 中模型的职责是什么?

    我一直对 模型 应该或不应该包含什么感到有点困惑 教程和示例经常相互矛盾 到目前为止 我一直在谨慎行事 我的模型只暴露 UI 内容 例如用于绑定到视图的属性以及验证逻辑 但是模型中包含其他业务逻辑是否可以接受 假设我想通过网络服务控制机械泵
  • 从 TransformedBitmap 对象中“跨越”困境

    我有一个 2208 x 3000 TransformedBitmap 对象 其格式为 Indexed8 我正在对其进行 CopyPixels 操作 我在用着 int formattedBitmap PixelWidth formattedB
  • 接收事件时闪烁选项卡标题

    我有一个基于选项卡的聊天应用程序 用户可以在不同的选项卡项目中与几个人聊天 我想通过闪烁选项卡标题来通知用户传入消息 以防用户正在与接收消息的选项卡以外的其他用户聊天 我如何在 WPF 中实现这一目标 一些例子将非常有用 此致 莫尔泰萨 您
  • StockTrader RI > 控制器、演示者,WTF?

    我目前正在学习如何通过 Prism 复合 WPF 项目高级使用 WPF 我观看了很多视频和示例 演示应用程序 StockTraderRI 让我提出了这个问题 以下各部分的具体作用是什么 SomethingService 好的 这是管理数据的
  • WPF - 为什么 Keyboard.Focus() 不起作用?

    TabItem 控件上有一个 TextBox 项 MyTextBox 我的代码如下所示 MyTextBox Focus Keyboard Focus MyTextBox 当我通过调试器运行此代码时 执行行后我会看到以下内容 MyTextBo
  • 如何设置和更改 WPF 中的文化

    我有一个 NET 4 0 WPF 应用程序 用户可以在其中更改语言 文化 我只是让用户选择一种语言 创建相应的 CultureInfo 并设置 Thread CurrentThread CurrentCulture cultureInfo
  • 将 RenderTargetBitmap 转换为 System.Drawing.Image

    我有 3D WPF 视觉对象 我想将其传递到 Excel 单元格 通过剪贴板缓冲区 对于 普通 BMP 图像 它可以工作 但我不知道如何转换RenderTargetBitmap 我的代码如下所示 System Windows Media I
  • 从 WPF 窗口中删除图标

    我可以使用 WinApi 从 WPF 窗口中删除窗口图标 但是当我仅运行 WPF 项目的可执行文件时 我会在应用程序窗口中再次获得该图标 如何删除该图标 From WPF教程 http www wpftutorial net RemoveI
  • XAML中无限旋转矩形

    如何定义XAML无限旋转矩形 到目前为止 我找到了一个带有代码但没有 xaml 的解决方案 http www codeproject com Articles 23257 Beginner s WPF Animation Tutorial
  • wpf缩放到文本框,当我单击文本框时,文本框无法显示光标

    Merged https meta stackexchange com questions 158066 what is a merged question with wpf缩放到文本框 当我单击文本框时 文本框无法显示光标 questio
  • 使用 MVVM 时 XamDataGrid 列可见性不起作用

    我正在尝试在 MVVM 架构中实现 XamDataGrid 列可见性 但它似乎不起作用 我正在执行以下操作 为未绑定字段添加可见性属性
  • Windows 更新 KB4040972/73 导致 WPF 类出现黑色图像

    我有一个依赖于深度缩放图像 从 PNG 转换为各种比例的 JPG 金字塔 的应用程序 我们使用 DeepZoomTools dll 来实现 这依赖于PresentationCore dll 多年来一直运行良好 推出 KB4040972 和
  • 如何重新启动 WPF 应用程序?

    如何从代码重新启动 WPF 应用程序 在 Windows 窗体中存在 Application Restart 但出于某种原因 Microsoft 决定不在 WPF 中添加此方法 我讨厌 WPF 和 Windows 窗体之间的不兼容 喜欢 w
  • CanExecute 何时被调用?

    在演示中 我有一个按钮可以切换布尔字段isAsking 我创建了一个命令 该命令仅在以下情况下执行isAsking true 一旦我按下切换按钮 okButton IsEnable立即更改 这表明该命令发现了更改isAsking 我感到很困
  • wpf自定义控件:另一个矩形内的可拖动/可调整大小的矩形

    我正在研究一个带有两个矩形的控件 一个在另一个矩形内 我希望用户能够拖动内部矩形 调整其大小 如果可能的话 也可以在外部矩形的边界内旋转它 这些值应该是可绑定的 以便我可以在更新时将这些值存储在我的数据源中 是否已经有这样的控件或者有人有任
  • wpf C# 中的内存泄漏

    我正在使用 GalaSoft MvvmLight 套件和 WPF Toolkit 开发 WPF MVVM v3 5 中 应用程序DataGrid and DatePicker 但是 每次加载应用程序时 我都会面临应用程序中的大量内存泄漏Us
  • 如何用ListBox制作自定义控件?

    我想用自定义的项目模板制作水平ListBox 所以我制作了它的基本模板 但是 我找不到将 事物 绑定到 WPF XAML 的示例 尤其是在 ListBox 填充了自定义项的情况下 我只是想动态添加 删除列表框中的项目 其中包含图像 标签 组
  • WPF TreeView:如何像在资源管理器中一样使用圆角设置所选项目的样式

    WPF TreeView 中的所选项目具有带有 尖 角的深蓝色背景 今天看来有点过时了 我想将背景更改为 Windows 7 资源管理器中的样子 带 不带焦点 到目前为止我所尝试的并没有删除原来的深蓝色背景 而是在其顶部绘制了一个圆形边框

随机推荐