c# - WPF 多重绑定(bind)失败。为什么?

标签 c# .net wpf data-binding multibinding

我有这个标记:

   <GroupBox BorderThickness="2">
    <GroupBox.BorderBrush>
        <SolidColorBrush x:Name="Border">
            <SolidColorBrush.Color>
                <MultiBinding Converter="{StaticResource ConnectionAndLoggedInToBorderBrush}">
                    <Binding Path="IsConnected"/>
                    <Binding Path="IsLoggedIn"/>
                </MultiBinding>
            </SolidColorBrush.Color>
        </SolidColorBrush>
    </GroupBox.BorderBrush>

在后面的代码中,我在 window_loaded 方法中有这一行:

DataContext = uiManager;

uiManager 属于 UIManager 类型,它具有两个名为 IsConnected 和 IsLoggedIn 的公共(public)属性。

此代码在启动时失败,因为 Multibinding 调用的 Converter 中的值数组未填充 bool 值,但具有 DependencyProperty.UnsetValue 值。

当我使用下面的标记(并更改转换器的返回类型)时,它确实有效。

   <GroupBox BorderThickness="2">
    <GroupBox.BorderBrush>
         <MultiBinding Converter="{StaticResource ConnectionAndLoggedInToBorderBrush}">
              <Binding Path="IsConnected"/>
              <Binding Path="IsLoggedIn"/>
         </MultiBinding>
    </GroupBox.BorderBrush>

似乎在第一个示例中通过后面代码中的 DataContext 设置的绑定(bind)失败,但在第二个示例中有效。为什么?

为了在 UIManager 类下面的完整性:

public class UIManager:IUIManager
    {

        #region Implementation of IUIManager

        private const string IsLoggedInProperty = "IsLoggedIn";
        private bool loggedIn;
        private readonly object loggedInLock = new object();
        public bool IsLoggedIn
        {
            get
            {
                lock (loggedInLock)
                {
                    return loggedIn;
                }
            }
            set
            {
                lock (loggedInLock)
                {
                    if(value==loggedIn)return;
                    loggedIn = value;
                    OnPropertyChanged(IsLoggedInProperty);
                }
            }
        }

        private void OnPropertyChanged(string property)
        {
            if(PropertyChanged!=null)PropertyChanged(this,new PropertyChangedEventArgs(property));
        }

        private const string IsConnectedProperty = "IsConnected";
        private bool isConnected;
        private object isConnectedLock = new object();
        public bool IsConnected
        {
            get
            {
                lock (isConnectedLock)
                {
                    return isConnected;
                }
            }
            set
            {
                lock (isConnectedLock)
                {
                    if(value==isConnected)return;
                    isConnected = value;
                    OnPropertyChanged(IsConnectedProperty);
                }
            }
        }

        #endregion

        #region Implementation of INotifyPropertyChanged

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion
    }

编辑: 失败 XAML 的转换方法(它在转换为值 [0] 的 bool 时失败:

public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            var is_connected = (bool) values[0];
            var is_loggedin = (bool) values[1];
            return is_loggedin
                       ? is_connected
                             ? Colors.YellowGreen
                             : Colors.Red
                       : Colors.Gray;
        }

对于工作 XAML:

public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            var is_connected = (bool) values[0];
            var is_loggedin = (bool) values[1];
            return is_loggedin
                       ? is_connected
                             ? Brushes.YellowGreen
                             : Brushes.Red
                       : Brushes.Gray;
        }

最佳答案

此问题与 MultiBinding 或您的转换器无关。 DependencyProperty.UnsetValue 表示绑定(bind)没有值。事实上,如果您在 Debug模式下运行,您可以在 Output 窗口中看到绑定(bind)错误:

System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=IsConnected; DataItem=null; target element is 'SolidColorBrush' (HashCode=17654054); target property is 'Color' (type 'Color')
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=IsLoggedIn; DataItem=null; target element is 'SolidColorBrush' (HashCode=17654054); target property is 'Color' (type 'Color')

所以让我们稍微简化标记并应用一些诊断:

<GroupBox>
    <GroupBox.BorderBrush>
        <SolidColorBrush>
            <SolidColorBrush.Color>
                <Binding Path="GroupColor" PresentationTraceSources.TraceLevel="High"/>
            </SolidColorBrush.Color>
        </SolidColorBrush>
    </GroupBox.BorderBrush>
</GroupBox>

应用附加的依赖属性 PresentationTraceSources.TraceLevel 产生更多输出:

System.Windows.Data Warning: 52 : Created BindingExpression (hash=17654054) for Binding (hash=44624228)
System.Windows.Data Warning: 54 :   Path: 'GroupColor'
System.Windows.Data Warning: 56 : BindingExpression (hash=17654054): Default mode resolved to OneWay
System.Windows.Data Warning: 57 : BindingExpression (hash=17654054): Default update trigger resolved to PropertyChanged
System.Windows.Data Warning: 58 : BindingExpression (hash=17654054): Attach to System.Windows.Media.SolidColorBrush.Color (hash=52727599)
System.Windows.Data Warning: 60 : BindingExpression (hash=17654054): Use Framework mentor <null>
System.Windows.Data Warning: 63 : BindingExpression (hash=17654054): Resolving source 
System.Windows.Data Warning: 65 : BindingExpression (hash=17654054): Framework mentor not found
System.Windows.Data Warning: 61 : BindingExpression (hash=17654054): Resolve source deferred
System.Windows.Data Warning: 91 : BindingExpression (hash=17654054): Got InheritanceContextChanged event from SolidColorBrush (hash=52727599)
System.Windows.Data Warning: 63 : BindingExpression (hash=17654054): Resolving source 
System.Windows.Data Warning: 66 : BindingExpression (hash=17654054): Found data context element: GroupBox (hash=51393439) (OK)
System.Windows.Data Warning: 67 : BindingExpression (hash=17654054): DataContext is null
System.Windows.Data Warning: 91 : BindingExpression (hash=17654054): Got InheritanceContextChanged event from SolidColorBrush (hash=52727599)
System.Windows.Data Warning: 63 : BindingExpression (hash=17654054): Resolving source 
System.Windows.Data Warning: 65 : BindingExpression (hash=17654054): Framework mentor not found
System.Windows.Data Warning: 63 : BindingExpression (hash=17654054): Resolving source 
System.Windows.Data Warning: 65 : BindingExpression (hash=17654054): Framework mentor not found
System.Windows.Data Warning: 63 : BindingExpression (hash=17654054): Resolving source  (last chance)
System.Windows.Data Warning: 65 : BindingExpression (hash=17654054): Framework mentor not found
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=GroupColor; DataItem=null; target element is 'SolidColorBrush' (HashCode=52727599); target property is 'Color' (type 'Color')

我们看到绑定(bind)没有找到 DataContext 并且绑定(bind)失败。当我更改 Windows 的构造函数以便在初始化绑定(bind)工作的内容之前设置 DataContext 时:

public Window1()
{
    DataContext = ...;
    InitializeComponent();
}

这很奇怪,因为对于其他地方的绑定(bind)来说这无关紧要。不知道为什么它在那里不起作用,所以我只能提供解决方法。例如,将画笔创建为具有绑定(bind)的资源(该资源也可以是 GroupBox 的本地资源):

<GroupBox BorderBrush="{DynamicResource resbrush}">
    <GroupBox.Resources>
        <SolidColorBrush x:Key="resbrush">
            <SolidColorBrush.Color>
                <MultiBinding Converter="{StaticResource ConnectionAndLoggedInToBorderBrush}">
                    <Binding Path="IsConnected"/>
                    <Binding Path="IsLoggedIn"/>
                </MultiBinding>
            </SolidColorBrush.Color>
        </SolidColorBrush>
    </GroupBox.Resources>
</GroupBox>

如果您的 UIManager 类是某种MVVM ViewModel

关于c# - WPF 多重绑定(bind)失败。为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1447055/

相关文章:

.net - 通过 .Net 的 Tarantool 队列

WPF ListView 忽略 SelectedItem 更改

c# - ItemsSource 绑定(bind)不更新值

C# LINQ to XML : how to join Xml Data

c# - 将 List<t> 转换或转换为 EntityCollection<T>

c# - 为什么我在 listView1 上没有属性项?

c# - 在 C# 中等待异步任务时会发生什么?

c# - 如何使用 `#import` 和 `tlb` 文件从 C# 程序集在 C++ 中实现 COM 回调接口(interface)?

c# - WPF DataBinding 监视抛出的异常

c# - 在线程中使用 C# 将字符串添加到 WPF 中的列表框