-1

In xaml Window.Resources I have defined a VisualBrush:

    <VisualBrush x:Name="LineVisualBrush" x:Key="LineVisualBrush" TileMode="Tile" Viewport="0,0,40,40" ViewportUnits="Absolute" Viewbox="0,0,40,40" ViewboxUnits="Absolute" PresentationOptions:Freeze="True">
        <VisualBrush.Visual>
            <Grid Background="Black">
                <Path Data="M 0 0 L 40 0" Stroke="White" />
            </Grid>
        </VisualBrush.Visual>
    </VisualBrush>

In code behind I need to change the Grid Background Color and the Path Stroke Color:

        VisualBrush vb = new VisualBrush();
        vb = (VisualBrush)Resources["LineVisualBrush"];

        vb.Visual.SetValue(Grid.BackgroundProperty, new SolidColorBrush(Colors.Red));
        vb.Visual.SetValue(Shape.StrokeProperty, new SolidColorBrush(Colors.Blue));

The problem is that it set the Path Stroke Color to Red instead of Blue and it don't change the Grid Background Color.

user2272143
  • 469
  • 5
  • 22
  • Have you considered instead of programmatically changing the color of the resource, you create a 2nd style resource that contains the new Background color and Path stroke, then you re-assign the Style for the Control programmatically? – Mac Oct 11 '19 at 16:02
  • @Mac Thanks for your answer. Unfortunately I have a lot of VisualBrushes created in Xaml and I need to change just the colors programmatically. In this example I change to Blue and Red but it could be any color and combination on user preference. – user2272143 Oct 11 '19 at 16:06
  • If you want to be able to modify the object, why do you use `PresentationOptions:Freeze`? Frankly, setting properties directly in code-behind is very much a poor design choice vs using view models and bindings to control things like this. But at the very least, if you want to be able to modify an object, you should probably not tell WPF that you want the object to not be modifiable. – Peter Duniho Oct 11 '19 at 16:45
  • @PeterDuniho I need PresentationOptions:Freeze for performances reasons however it is not that the problem since I create a new VisualBrush from the Resources and it is modificable, Then I freeze it again before to assign it to the Control Background. I need to do it programmatically because I have to read the colors from a settings file – user2272143 Oct 11 '19 at 17:00
  • _"I create a new VisualBrush from the Resources"_ -- please explain that statement. Because, the only code you posted does _not_ create a new object. – Peter Duniho Oct 11 '19 at 17:02
  • VisualBrush vb = new VisualBrush(); vb = (VisualBrush)Resources["LineVisualBrush"]; But it work correctly for the properties of the first element in the Visual.I don't know how to set the properties of the child – user2272143 Oct 11 '19 at 17:38
  • Btw, If I don't find a solution I'll just ask to the other department to remove the grid and change the path with a polygon in the VisualBrushes in Xalm so I can change the properties how I have made in this example – user2272143 Oct 11 '19 at 17:46
  • Reiterating the code you posted is in no way an _explanation_. The code you quoted, does not _"create a new VisualBrush from the Resources"_. It simply retrieves the instance that is in the `ResourceDictionary` already. Maybe you are confused because you think that the assignment `vb = new VisualBrush()` does something useful. **It does not**. The very next statement discards the object you just created, in favor of the object retrieved from the resources. – Peter Duniho Oct 12 '19 at 00:25

1 Answers1

1

I have found the problems.

First. The Grid in Xaml have Height 0 for this reason the background is not visible. But I think because of Antialias a part of the color is visible in the Path. Adding an Height to the Grid it fix the problem about Background color.

<VisualBrush x:Name="LineVisualBrush" x:Key="LineVisualBrush" TileMode="Tile" Viewport="0,0,40,40" ViewportUnits="Absolute" Viewbox="0,0,40,40" ViewboxUnits="Absolute" PresentationOptions:Freeze="True">
    <VisualBrush.Visual>
            <Grid Background="Black" Height = 40>
            <Path Data="M 0 0 L 40 0" Stroke="White" />
        </Grid>
    </VisualBrush.Visual>
</VisualBrush>

Second. I need to access the children of the Visual in code behind to change te Stroke color of the Path. I changed the code in this way and now it works perfectly.

VisualBrush vb = (VisualBrush)Resources["LineVisualBrush"];
Grid grid = (Grid)vb.Visual;
System.Windows.Shapes.Path path = (System.Windows.Shapes.Path)grid.Children[0];
grid.Background = new SolidColorBrush(Colors.Red);
path.Stroke = new SolidColorBrush(Colors.Blue);
user2272143
  • 469
  • 5
  • 22