WPF MultiBinding Ausfällt. Warum?
Habe ich dieses Markup:
<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>
In der code-behind habe ich diese Zeile in den window_loaded-Methode:
DataContext = uiManager;
uiManager ist der Typ UIManager, hat zwei öffentliche Eigenschaften mit den Namen IsConnected und IsLoggedIn.
Dieser code schlägt fehl, beim Start, weil die Werte-array in den Konverter, das heißt durch die Multibinding ist nicht gefüllt mit booleans, haben aber einen Wert von DependencyProperty.UnsetValue.
Wenn ich den markup unten (und ändern Sie den returntype von dem Konverter) funktioniert es.
<GroupBox BorderThickness="2">
<GroupBox.BorderBrush>
<MultiBinding Converter="{StaticResource ConnectionAndLoggedInToBorderBrush}">
<Binding Path="IsConnected"/>
<Binding Path="IsLoggedIn"/>
</MultiBinding>
</GroupBox.BorderBrush>
Es scheint, dass die Bindung durch den DataContext in der code-behind scheitert im ersten Beispiel, funktioniert aber in der zweiten. Warum?
Vollständigkeit unterhalb der UIManager-Klasse:
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
}
BEARBEITEN:
Die Umwandlung Methode, die für die fehlerhafte XAML (es scheitert an der Konvertierung zu bool Werte[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;
}
für die arbeiten 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;
}
Ich habe den Konverter-Methode. Ich muss setzen Sie die Farbe-Eigenschaft, um in der Lage sein zu implementieren ColorAninmation. Das ist an sich funktioniert mit dem ersten XAML, wenn ich entfernen Sie die MultiBinding.
InformationsquelleAutor Dabblernl | 2009-09-18
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dem problem nichts zu tun hat mit einem
MultiBinding
oder euren converter.DependencyProperty.UnsetValue
bedeutet, dass die Bindung bekam keinen Wert. Und in der Tat, wenn Sie ausführen im debug-Modus sehen Sie verbindlich, Fehler in derOutput
Fenster:Also wir vereinfachen die markup ein bisschen und gelten einige Diagnose:
Anwendung der angefügte Abhängigkeitseigenschaft
PresentationTraceSources.TraceLevel
ergibt etwas mehr Leistung:Sehen wir, dass die Bindung nicht finden
DataContext
und die Bindung fehlschlägt. Wenn ich die windows-Konstruktor so, dassDataContext
festgelegt ist, bevor die Initialisierung des content die Bindung funktioniert:Welche ist seltsam, da für Bindungen in anderen Orten ist dies nicht relevant. Nicht sicher, warum es nicht funktioniert da kann ich ja nur workarounds. Was funktioniert ist zum Beispiel die Erstellung der Bürste, wie eine Ressource, die mit den Bindungen (die Ressource kann auch lokal auf dem
GroupBox
):Ich würde vorschlagen, allerdings fallen die
MultiBinding
und zu tun, einige vor der Verarbeitung in derDataContext
wenn IhrUIManager
Klasse ist eine Art vonMVVM
ViewModel
.InformationsquelleAutor gix
Meine Theorie. Farbe ist struct (darf nicht null sein), so SolidColorBrush.Color = null falsch ist. WPF kann nicht erstellt SolidColorBrush, und Sie erhalten die Ausnahme.
BorderBrush-Objekt (kann null sein), so GroupBox.BorderBrush = null ist OK.
Dieses SolidColorBrush ist nicht ein Objekt, sondern eine FABRIK. Es ist erst dann instanziiert, wenn nötig, und an diesem Punkt, die Sie bereits angebracht haben, DataContext.
Just my 2 cents.
Lesen Sie meinen Artikel, btw, könnte nützlich sein, wenn Sie einige seltsame Bindungen oder Animationen mit seltsamen Wandler. http://www.codeproject.com/KB/WPF/BindingHub.aspx
InformationsquelleAutor agroskin
Ist es aus Gründen wie diese, wollen Sie vielleicht lernen MVVM. Dieses Muster hilft Ihnen zu abstrahieren, das Modell und Bindungen, so dass Sie nicht haben, zu verlassen sich so stark auf die DPs - Sie können ganz einfach binden einen meldepflichtigen Eigenschaft in einem Modell statt.
Es gibt mehrere ausgezeichnete Artikel über MVVM, so würde ich vorschlagen, Sie starten durch die Lektüre der Werke von Karl Shifflett, Josh Smith, Marlon Grech und Sacha Barber.
InformationsquelleAutor Pete OHanlon