Reputation: 585
I just try to create a simple Symbol/Geometry/Control and change and reuse it in several places in the same window.
Example: a black square with a circle in the middle.
The circle should then change between red and green (similar to a one-light stoplight). Doing it with images would work. I try to solve it as a Window resource, but I do not unterstand.
The idea: I write it into a resource, here I try into a Canvas:
<Window.Resources>
<Canvas x:Key="Ampel">
<Rectangle Fill="Black" HorizontalAlignment="Left" Height="52" Stroke="Black" VerticalAlignment="Top" Width="50"/>
<Ellipse x:Name="RedGreen" Fill="Red" HorizontalAlignment="Left" Height="27" Margin="11,12,0,0" Stroke="Black" VerticalAlignment="Top" Width="28" RenderTransformOrigin="0.214,0.256"/>
</Canvas>
</Window.Resources>
Then I would like to place it inside a Grid or a Panel, but how do I reference it?
<Canvas x:Name="RedGreen1" Height="50" Width="50" DataContext="{DynamicResource Ampel}" />
This does not return a compiler-error, but shows nothing in the window. It also doesn't work with WrapPanel or anything else.
And if it would work, how could I refer to it in code-behing for changing the color of the circle. Something like RedGreen1.RedGreen.Fill=Brushes.Green
?
I read the articles about stoplights. Is it really necessary to create an UserControl or is there a way to solve it with window.resources?
General idea of the application is to have a list of parameters. Each one with a correct input is marked green and computation can only be started, if all parameters are marked green.
And even if I get it running with red/green-images, I try to understand WPF/XAML better and learn something.
Thank you.
Upvotes: 35
Views: 20052
Reputation: 22702
When you define a arbitrary Control in Resources
, you can use it in the future in Control which have property Content
and derived from Control
class. These are the followings: ContentControl
, Label
, ContentPresenter
, etc.
Also you must set x:Shared="False"
for resource if you want to use this resource in many Controls, because x:Shared="True"
by default then one Resource is common to all - in this case, the system swears on the duplicate Content. When x:Shared="False"
when is created Resource for each element whenever it its request. Quote from MSDN
:
When set to false, modifies WPF resource-retrieval behavior so that requests for the attributed resource create a new instance for each request instead of sharing the same instance for all requests.
Example:
<Window.Resources>
<Canvas x:Key="Ampel" x:Shared="False">
<Rectangle Fill="Black" HorizontalAlignment="Left" Height="52" Stroke="Black" VerticalAlignment="Top" Width="50"/>
<Ellipse x:Name="RedGreen" Fill="Red" HorizontalAlignment="Left" Height="27" Margin="11,12,0,0" Stroke="Black" VerticalAlignment="Top" Width="28" />
</Canvas>
</Window.Resources>
<Grid>
<ContentControl Name="MyContentControl" Content="{StaticResource Ampel}" HorizontalAlignment="Left" />
<Label Name="MyLabel" Content="{StaticResource Ampel}" HorizontalAlignment="Center" />
<ContentPresenter Name="MyContentPresenter" Content="{StaticResource Ampel}" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
To change the Fill
of Ellipse in code-behind, you can like this:
private void ChangeBackground_Click(object sender, RoutedEventArgs e)
{
var canvas = MyContentControl.Content as Canvas;
if (canvas != null)
{
foreach (var item in canvas.Children)
{
if (item is Ellipse)
{
((Ellipse)item).Fill = Brushes.Green;
}
}
}
}
Upvotes: 37
Reputation: 8654
canvas is not having template property thats why we are using contencontrol here.
<Window.Resources>
<ControlTemplate x:Key="Ampel" TargetType="ContentControl">
<Canvas>
<Rectangle Fill="Black" HorizontalAlignment="Left" Height="52" Stroke="Black" VerticalAlignment="Top" Width="50"/>
<Ellipse x:Name="RedGreen" Fill="{Binding Path=Tag, RelativeSource={RelativeSource TemplatedParent}}" HorizontalAlignment="Left" Height="27" Margin="11,12,0,0" Stroke="Black" VerticalAlignment="Top" Width="28" RenderTransformOrigin="0.214,0.256"/>
</Canvas>
</ControlTemplate>
</Window.Resources >
<ContentControl Template="{StaticResource Ampel}" Tag="Red" ></ContentControl>
<ContentControl Template="{StaticResource Ampel}" Tag="Green" ></ContentControl>
<ContentControl Template="{StaticResource Ampel}" Tag="Blue" ></ContentControl>
Output
Upvotes: 9
Reputation: 95
You can use C# code by heritage:
public class customBottum : Buttom
{
int var1;
bool var2;
public customBottum()
{
InitializeComponent();
}
other function ...
}
Upvotes: -2