Autor |
Beitrag |
ebber
      
Beiträge: 239
Erhaltene Danke: 1
Win XP, Win 7
C# (VS 2010), Delphi (2007), Expression 4
|
Verfasst: Sa 19.03.11 00:12
Hallo,
ich habe ein kleines Problem, und zwar habe ich in XAML eine Farbe:
XML-Daten 1: 2: 3:
| <Application.Resources> <ResourceDictionary> <Color x:Key="sgBlueCol">#FF00A8FF</Color> |
Diese möchte ich jetzt im Code verändern:
C#-Quelltext 1: 2:
| Color bs = (Color)Application.Current.FindResource("sgBlueCol"); bs = meineNeueFarbe; |
Die Farbe bekomme ich so ja zurück, aber es passiert nix. Also ich verwende die Farbe dann wieder so:
XML-Daten 1:
| Color="{DynamicResource sgBlueCol}" |
und da soll sie sich verändern
MfG
|
|
Kha
      
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: Sa 19.03.11 00:33
Warum soll auch das Zuweisen einer lokalen Variablen das ResourceDictionary beeinflussen? Du musst schon über dessen Indexer den neuen Wert fesetlegen.
_________________ >λ=
|
|
ebber 
      
Beiträge: 239
Erhaltene Danke: 1
Win XP, Win 7
C# (VS 2010), Delphi (2007), Expression 4
|
Verfasst: Sa 19.03.11 00:47
 Ich glaub da war ich ziemlich verwirrt. Nu ist mir klar wiso nix passiert.
Aber wie schaffe ich es, das was passiert, hast du ein kurzes Beispiel, oder das Wort nach dem ich Googeln sollte?
|
|
Trashkid2000
      
Beiträge: 561
Erhaltene Danke: 137
|
Verfasst: Sa 19.03.11 14:49
Hi,
warum machst Du das Ganze denn nicht über ein Binding an eine Property?
Also so:
XML-Daten 1:
| Color="{Binding Path=Color, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}" | Dann kannst Du Dir das mit FindResource schenken, und das ist auch nicht so Fehleranfällig. Im schlimmsten Fall bekommst Du eine BindingException.
|
|
ebber 
      
Beiträge: 239
Erhaltene Danke: 1
Win XP, Win 7
C# (VS 2010), Delphi (2007), Expression 4
|
Verfasst: Sa 19.03.11 17:08
In einem andern Fall wäre das bestimmt eine gute Lösung, aber ich verwende die Farbe an ca 30 Stellen im Programm und dann müsste ich ja an jeder das Binding hinzufügen. Und ich nehme mal an das kommt anderen Bindings irgendwie in die gwere.
|
|
Trashkid2000
      
Beiträge: 561
Erhaltene Danke: 137
|
Verfasst: Sa 19.03.11 21:10
Na gut, wenn das zu viel Arbeit macht (aber 30 Stellen hat man schnell geändert) hast Du auch die Möglichkeit, die Farbe im RecourceDictionary zu ändern:
C#-Quelltext 1: 2: 3:
| ResourceDictionary dic = Application.Current.Resources; if (dic.Contains("sgBlueCol")) dic["sgBlueCol"] = Color.Black; | Aber naja.
LG, Marko
|
|
SakeSushi
      
Beiträge: 17
Windows 7
C# 4.0, Visual Studio 2010, Powershell 2.0
|
Verfasst: So 20.03.11 14:12
Du darfst aber nicht vergessen, dass du dann eine dynamische Resource und nicht eine statische haben willst.
Deswegen müssen die Resource-Verweise bei den Elementen so aussehen:
XML-Daten 1:
| <Button Background="{DynamicResource resource}" /> |
|
|
ebber 
      
Beiträge: 239
Erhaltene Danke: 1
Win XP, Win 7
C# (VS 2010), Delphi (2007), Expression 4
|
Verfasst: So 20.03.11 14:57
@SakeSushi: Danke für die Erinnerung.
@Trashkid2000: Irgendwiewas funktioniert bei mir noch nicht, er findet "sgBlueCol" und setzt theoretisch auch die Farbe, aber es verfärbt sich nichts. Muss ich da irgendwie noch ein neuzeichnen auslösen oder gibts es da auch so eine Eigenschaft wie "TwoWay"?
MfG
//Edit: Ich glaube ich bin schon wieder auf dem Schlauch gestanden, mir scheint das gleiche Problem wie am Anfang, aber wie bekomme ich meine Änderung dann zurück ohne das komplette ResourceDictionary zu überschreiben?
|
|
SakeSushi
      
Beiträge: 17
Windows 7
C# 4.0, Visual Studio 2010, Powershell 2.0
|
Verfasst: So 20.03.11 16:19
Zitat: | Irgendwiewas funktioniert bei mir noch nicht, er findet "sgBlueCol" und setzt theoretisch auch die Farbe, aber es verfärbt sich nichts. Muss ich da irgendwie noch ein neuzeichnen auslösen oder gibts es da auch so eine Eigenschaft wie "TwoWay"? |
Es muss weder ein "BindingMode" angegeben noch ein Event gestartet werden. Ich hab hier mal ein kurzes Beispiel-Programm geschrieben:
Abb.xaml
XML-Daten 1: 2: 3:
| <Application.Resources> <ResourceDictionary Source="Dictionary1.xaml" /> </Application.Resources> |
MainWindow.xaml
XML-Daten 1: 2: 3: 4: 5: 6:
| <Grid Background="{DynamicResource light}"> <StackPanel Width="200" Height="50" VerticalAlignment="Center" HorizontalAlignment="Center"> <Button x:Name="one" Click="one_Click" Content="Blanched Almond" /> <Button x:Name="two" Click="two_Click" Content="Azure" /> </StackPanel> </Grid> |
Button EventHandlers
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| private void one_Click(object sender, RoutedEventArgs e) { ResourceDictionary my_dictionary = App.Current.Resources; if(my_dictionary.Contains("light")) my_dictionary["light"] = Brushes.BlanchedAlmond; }
private void two_Click(object sender, RoutedEventArgs e) { ResourceDictionary my_dictionary = App.Current.Resources; if (my_dictionary.Contains("light")) my_dictionary["light"] = Brushes.Azure; } |
Bei mir funktioniert es so wunderbar.
Zitat: | [...]aber wie bekomme ich meine Änderung dann zurück ohne das komplette ResourceDictionary zu überschreiben? |
Beziehst du dich hier auf diesen Code?
C#-Quelltext 1: 2: 3:
| ResourceDictionary my_dictionary = App.Current.Resources; if(my_dictionary.Contains("light")) my_dictionary["light"] = Brushes.BlanchedAlmond; |
|
|
ebber 
      
Beiträge: 239
Erhaltene Danke: 1
Win XP, Win 7
C# (VS 2010), Delphi (2007), Expression 4
|
Verfasst: So 20.03.11 16:55
Danke für die ganze Arbeit, so funktioniert es bei mir auch. Das erkärt wohl auch wo das Problem liegt.
Ich habe aber leider keine Ahnung wieso es da ein Problem gibt.
Ich verwende ja keinen Brush sondern eine Color :
XML-Daten 1:
| <Color x:Key="sgBlueCol">#FF00A8FF</Color> |
diese wird dann wiederum in einem Brush verwendet:
XML-Daten 1: 2: 3: 4:
| <LinearGradientBrush x:Key="sgBackground" EndPoint="0.463,-0.064" StartPoint="0.563,2.742"> <GradientStop Color="White" Offset="1"/> <GradientStop Color="{DynamicResource sgBlueCol}"/> </LinearGradientBrush> |
Ich könnte diesen Brush natürlich auch im Code erstellen, aber ich verwende die Farbe in mehreren unterschiedlichen Brushes, deshalb wäre es mir schon lieber es würde so funktionieren.
|
|
Kha
      
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: So 20.03.11 17:14
Ich denke nicht, dass dieser Fall abgedeckt wird:
msdn.microsoft.com/e...3.aspx#staticdynamic hat folgendes geschrieben: | Dynamic resource references have some notable restrictions. At least one of the following must be true:
* The property being set must be a property on a FrameworkElement or FrameworkContentElement. That property must be backed by a DependencyProperty.
* The reference is for a value within a Style Setter.
* The property being set must be a property on a Freezable that is provided as a value of either a FrameworkElement or FrameworkContentElement property, or a Setter value.
|
Da ich noch nie mit DynamicResource gearbeitet habe, bin ich mir auch nicht sicher, was die praktischste Lösung wäre.
_________________ >λ=
|
|
SakeSushi
      
Beiträge: 17
Windows 7
C# 4.0, Visual Studio 2010, Powershell 2.0
|
Verfasst: So 20.03.11 17:36
Es funktioniert wenn die Resourcen in der gleichen XAML-Datei leigen.
Anscheinend muss man beim auslagern in ein ResourceDictionary irgendetwas beachten. Ich habe zwar gelesen, dass man bei den Brushes x:Shared auf "false" setzen soll, kann abe ranch bestätigen das es funktioniert ^^
modifizierte MainWindow.xaml
XML-Daten 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| <Window.Resources> <Color x:Key="c1">White</Color> <LinearGradientBrush x:Key="sgBackground" EndPoint="0.463,-0.064" StartPoint="0.563,2.742"> <GradientStop Color="White" Offset="1"/> <GradientStop Color="{DynamicResource c1}"/> </LinearGradientBrush> </Window.Resources> <Grid Background="{DynamicResource sgBackground}"> <StackPanel ... /> </Grid> |
|
|
ebber 
      
Beiträge: 239
Erhaltene Danke: 1
Win XP, Win 7
C# (VS 2010), Delphi (2007), Expression 4
|
Verfasst: So 20.03.11 18:04
Kann ich auch bestätigen, dass das funktioniert. Aber wie könnte es auch anders sein, verwende ich die Farbe natürlich in mehreren Windows
Falls jemand noch die perfekte Lösung findet wäre das toll , ansonsten danke schonmal.
MfG
|
|
SakeSushi
      
Beiträge: 17
Windows 7
C# 4.0, Visual Studio 2010, Powershell 2.0
|
Verfasst: So 20.03.11 22:21
Ich habe nach etwas herumprobieren doch noch einen Lösungsweg gefunden:
Die Colors, welche du für die ganzen Brushes einsetzt musst du in einer eigenen Resource Dictionary Datei lagen, welche du wie gewohnt in der App.xaml einbindest.
Die Brushes welche dynamisch an die Colors gebunden sind gibst du auch in eine eigene resource Dictionary Datei, welche du aber nicht in der App.xaml einbindest sondern nur in den Windows/Usercontrols die du brauchst.
Ich weiß zwar nicht genau warum die dynamischen Bindings in einem Resource Dictionary (intern) nicht funktionieren, aber anscheinend werden Dictionaries, welche in der App.xaml eingebunden werden irgendwie gefreezt (mehr kann ich dir aber auch nicht sagen  )
Naja, es ist besser als in jedem Window die ganzen Brushes neu zu definieren ...
|
|
ebber 
      
Beiträge: 239
Erhaltene Danke: 1
Win XP, Win 7
C# (VS 2010), Delphi (2007), Expression 4
|
Verfasst: Di 22.03.11 12:33
Danke
so hab ich mir das vorgestellt.
|
|
SakeSushi
      
Beiträge: 17
Windows 7
C# 4.0, Visual Studio 2010, Powershell 2.0
|
Verfasst: Di 22.03.11 13:01
|
|