我有这个标记:
<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的公共属性.
此代码在启动时失败,因为Multibinding调用的Converter中的values数组未填充布尔值,但值为DependencyProperty.UnsetValue.
当我使用下面的标记(并更改转换器的返回类型)时,它确实有效.
<GroupBox BorderThickness="2"> <GroupBox.BorderBrush> <MultiBinding Converter="{StaticResource ConnectionAndLoggedInToBorderBrush}"> <Binding Path="IsConnected"/> <Binding Path="IsLoggedIn"/> </MultiBinding> </GroupBox.BorderBrush>
在第一个示例中,似乎通过后面代码中的DataContext的绑定集失败,但在第二个示例中工作.为什么?
为了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的转换方法(在转换为bool值[0]时失败:
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,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表示绑定没有值.事实上,如果您在调试模式下运行,您可以在“输出”窗口中看到绑定错误:
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')
我们看到绑定没有找到DataContext,绑定失败.当我更改windows的构造函数以便在初始化内容之前设置DataContext,绑定有效:
public Window1() { DataContext = ...; InitializeComponent(); }
这很奇怪,因为在其他地方绑定并不重要.不知道为什么它不起作用所以我只能提供解决方法.例如,使用绑定创建画笔作为资源(该资源也可以是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,我建议删除MultiBinding并在DataContext中进行一些预处理.