Autor Beitrag
ebber
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 239
Erhaltene Danke: 1

Win XP, Win 7
C# (VS 2010), Delphi (2007), Expression 4
BeitragVerfasst: Sa 19.03.11 00:12 
Hallo,

ich habe ein kleines Problem, und zwar habe ich in XAML eine Farbe:

ausblenden XML-Daten
1:
2:
3:
<Application.Resources>
   <ResourceDictionary>
       <Color x:Key="sgBlueCol">#FF00A8FF</Color>


Diese möchte ich jetzt im Code verändern:

ausblenden 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:

ausblenden XML-Daten
1:
Color="{DynamicResource sgBlueCol}"					


und da soll sie sich verändern

MfG
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 239
Erhaltene Danke: 1

Win XP, Win 7
C# (VS 2010), Delphi (2007), Expression 4
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 561
Erhaltene Danke: 137



BeitragVerfasst: Sa 19.03.11 14:49 
Hi,
warum machst Du das Ganze denn nicht über ein Binding an eine Property?
Also so:
ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 239
Erhaltene Danke: 1

Win XP, Win 7
C# (VS 2010), Delphi (2007), Expression 4
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 561
Erhaltene Danke: 137



BeitragVerfasst: 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:
ausblenden C#-Quelltext
1:
2:
3:
ResourceDictionary dic = Application.Current.Resources;
if (dic.Contains("sgBlueCol"))
  dic["sgBlueCol"] = Color.Black;
Aber naja.
LG, Marko
SakeSushi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 17

Windows 7
C# 4.0, Visual Studio 2010, Powershell 2.0
BeitragVerfasst: 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:
ausblenden XML-Daten
1:
<Button Background="{DynamicResource resource}" />					
ebber Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 239
Erhaltene Danke: 1

Win XP, Win 7
C# (VS 2010), Delphi (2007), Expression 4
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 17

Windows 7
C# 4.0, Visual Studio 2010, Powershell 2.0
BeitragVerfasst: 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
ausblenden XML-Daten
1:
2:
3:
<Application.Resources>
        <ResourceDictionary Source="Dictionary1.xaml" />
</Application.Resources>


MainWindow.xaml
ausblenden 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
ausblenden 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?
ausblenden C#-Quelltext
1:
2:
3:
ResourceDictionary my_dictionary = App.Current.Resources;
if(my_dictionary.Contains("light"))
    my_dictionary["light"] = Brushes.BlanchedAlmond;
ebber Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 239
Erhaltene Danke: 1

Win XP, Win 7
C# (VS 2010), Delphi (2007), Expression 4
BeitragVerfasst: 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 :

ausblenden XML-Daten
1:
<Color x:Key="sgBlueCol">#FF00A8FF</Color>					


diese wird dann wiederum in einem Brush verwendet:
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 17

Windows 7
C# 4.0, Visual Studio 2010, Powershell 2.0
BeitragVerfasst: 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
ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 239
Erhaltene Danke: 1

Win XP, Win 7
C# (VS 2010), Delphi (2007), Expression 4
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 17

Windows 7
C# 4.0, Visual Studio 2010, Powershell 2.0
BeitragVerfasst: 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 :x )

Naja, es ist besser als in jedem Window die ganzen Brushes neu zu definieren ...
ebber Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 239
Erhaltene Danke: 1

Win XP, Win 7
C# (VS 2010), Delphi (2007), Expression 4
BeitragVerfasst: Di 22.03.11 12:33 
Danke :)

so hab ich mir das vorgestellt.
SakeSushi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 17

Windows 7
C# 4.0, Visual Studio 2010, Powershell 2.0
BeitragVerfasst: Di 22.03.11 13:01 
user profile iconebber hat folgendes geschrieben Zum zitierten Posting springen:
Danke :)

so hab ich mir das vorgestellt.


no problem dude