WPF Application how to convert grid background xaml to c#? - c#

I have a wpf app that I would like to allow the user to switch the 'Theme', which is simply the grid background.
This is the XAML:
<Grid x:Name="rabGrid">
<Grid.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF080D39"/>
<GradientStop Color="White"/>
<GradientStop Color="#FF838589" Offset="1"/>
<GradientStop Color="#FF2E4999" Offset="0.997"/>
</LinearGradientBrush>
</Grid.Background>
Here's what I have in c#:
private void rTheme_Click(object sender, RoutedEventArgs e)
{
LinearGradientBrush rabThem = new LinearGradientBrush();
rabThem.StartPoint = new Point(0.5, 0);
rabThem.EndPoint = new Point(0.5, 1);
GradientStop rabThemStop = new GradientStop();
rabThemStop.Color = Color.FromArgb(100, 8, 13, 57);
GradientStop rabThemStop1 = new GradientStop();
rabThemStop1.Color = Colors.White;
GradientStop rabThemStop2 = new GradientStop();
rabThemStop2.Color = Color.FromArgb(100, 131, 133, 137);
rabThemStop2.Offset = 1;
GradientStop rabThemStop3 = new GradientStop();
rabThemStop3.Color = Color.FromArgb(100, 46, 73, 153);
rabThemStop3.Offset = .997;
}
My idea behind the above code is to setup all the metrics, then somehow fill to the background.
I have also tried variations like this with no joy:
clasGrid.Background = new LinearGradientBrush();
clasGrid.StartPoint = new Point(0.5, 0);
clasGrid.EndPoint = new Point(0.5, 1);
I'm can change the background with something like this:
clasGrid.Background = new LinearGradientBrush(Colors.LightBlue, Colors.SlateBlue, 90);
Implementing some of the syntax from the answer below, I've came up with this:
LinearGradientBrush rabThem = new LinearGradientBrush();
rabThem.EndPoint = new Point(0.5, 1);
rabThem.StartPoint = new Point(0.5, 0);
GradientStop rabThemStop = new GradientStop();
rabThemStop.Color = Color.FromArgb(100, 8, 13, 57);
GradientStop rabThemStop1 = new GradientStop();
rabThemStop1.Color = Colors.White;
GradientStop rabThemStop2 = new GradientStop();
rabThemStop2.Color = Color.FromArgb(100, 131, 133, 137);
rabThemStop2.Offset = 1;
GradientStop rabThemStop3 = new GradientStop();
rabThemStop3.Color = Color.FromArgb(100, 46, 73, 153);
rabThemStop3.Offset = .997;
rabThem.GradientStops.Add(rabThemStop);
rabThem.GradientStops.Add(rabThemStop1);
rabThem.GradientStops.Add(rabThemStop2);
rabThem.GradientStops.Add(rabThemStop3);
clasGrid.Background = rabThem;
While this works, the colors are a lot lighter (as if the gradient is not correct) and am still trying to figure that part out.

You have to set up the gradient each time. You can either make a method for it, or you can make a converter. I'm using a boolean to control which background is used, but you can use whatever value you want. If you choose to make a method, you can base it off of my converter.
public class OptionOrderBackgroundConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
// Create a background and return
bool b = (value != null ? (bool)value : false);
if (!b)
{
LinearGradientBrush lb = new LinearGradientBrush();
lb.StartPoint = new System.Windows.Point(0, 0);
lb.EndPoint = new System.Windows.Point(0, 1);
GradientStop gstop = new GradientStop(ViewModels.QuoteButtonStyle.Instance.QuoteButtonTopBackgroundColor, 0);
lb.GradientStops.Add(gstop);
gstop = new GradientStop(ViewModels.QuoteButtonStyle.Instance.QuoteButtonBottomBackgroundColor, 0.9);
lb.GradientStops.Add(gstop);
return lb;
}
else
{
LinearGradientBrush lb = new LinearGradientBrush();
lb.StartPoint = new System.Windows.Point(0, 0);
lb.EndPoint = new System.Windows.Point(0, 1);
GradientStop gstop = new GradientStop(Colors.Orange, 0);
lb.GradientStops.Add(gstop);
gstop = new GradientStop(Colors.WhiteSmoke, 0.9);
lb.GradientStops.Add(gstop);
return lb;
}
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
For the converter, I bind it to the control like this:
Background="{Binding Path=IsDealable, FallbackValue=False, Converter={StaticResource OptionOrderBackgroundConverter}}"
If you use a converter and want to be able to pass in 2 colors, you can change it to an IMultiValueConverter.

Related

Dynamically Combining Rectangles

I'm trying to combine two rectangles that I need to create dynamically but I can't figure out how to draw them using .Data and I don't know how to convert from Windows.Shapes.Rectangle to Windows.Media.Geometry.
Rectangle Cross1 = new Rectangle();
Cross1.Margin = new Thickness(465, -140, 0, 0);
Cross1.Height = 110;
Cross1.Width = 15;
Cross1.RenderTransform = rotateTransform1;
Rectangle Cross2 = new Rectangle();
Cross2.HorizontalAlignment = HorizontalAlignment.Left;
Cross2.VerticalAlignment = VerticalAlignment.Top;
Cross2.Margin = new Thickness(362, -103, 0, 0);
Cross2.Height = 110;
Cross2.Width = 15;
Cross2.RenderTransform = rotateTransform2;
CombinedGeometry c1 = new CombinedGeometry(GeometryCombineMode.Union, Cross1, Cross2);
The CombinedGeometry class only works with other System.Windows.Media.Geometry objects, not System.Windows.Shapes. You need to use the equivalent RectangleGeometry class instead.
Something such as:
RectangleGeometry Cross1 = new RectangleGeometry(new Rect(0, 0, 15, 110));
Cross1.Transform = rotateTransform1;
RectangleGeometry Cross2 = new RectangleGeometry(new Rect(0, 0, 15, 110));
Cross2.Transform = rotateTransform2;
CombinedGeometry c1 = new CombinedGeometry(GeometryCombineMode.Union, Cross1, Cross2);

Using Dynamic Foreground with LinearGradientBrush

I'm working on a WPF application for my first time
I have a button that when clicked on will change its foreground color.
I felt regular colors are boring so I did some Linear Gradients to make it look better.
on C# I wrote.
// Here I create a Linear Gradient bush, a Collection of gradient stops, and the gradient stops I need and a brushconverter to get color codes #Fxxxx into color
BrushConverter bc = new BrushConverter();
public LinearGradientBrush MetallicBlue= new LinearGradientBrush();
public GradientStopCollection BlueG = new GradientStopCollection();
public GradientStop BGS1 = new GradientStop();
public GradientStop BGS2 = new GradientStop();
public GradientStop BGS3 = new GradientStop();
public GradientStop BGS4 = new GradientStop();
// Then I define each gradient stop and add it to the GradientStop Collection
BGS1.Color = (Color)bc.ConvertFrom("#FF094AAD");
BGS1.Offset = 0.244;
BGS2.Color = (Color)bc.ConvertFrom("#FF0745AA");
BGS2.Offset = 0.988;
BGS3.Color = (Color)bc.ConvertFrom("#FF286ED1");
BGS3.Offset = 0.5;
BGS4.Color = (Color)bc.ConvertFrom("#FF094AAD");
BGS4.Offset = 0.076;
BlueG.Add(BGS1);
BlueG.Add(BGS2);
BlueG.Add(BGS3);
BlueG.Add(BGS4);
// Here I set my Metallic Blue with Properties
MetallicBlue.StartPoint = new Point(0.5, 0);
MetallicBlue.EndPoint = new Point(0.5, 1);
MetallicBlue.GradientStops = BlueG;
On my click event when I set the color foreground it changes to blank! Text disappears.
textBlock.Foreground = MetallicBlue;
Can anyone help me out.
I want to implement this on many buttons but It does not quite work.
what am I missing.
A BrushConverter returns a Brush. You should use a ColorConverter. This works fine for me:
ColorConverter cc = new ColorConverter();
LinearGradientBrush MetallicBlue = new LinearGradientBrush();
GradientStopCollection BlueG = new GradientStopCollection();
GradientStop BGS1 = new GradientStop();
GradientStop BGS2 = new GradientStop();
GradientStop BGS3 = new GradientStop();
GradientStop BGS4 = new GradientStop();
BGS1.Color = (Color)cc.ConvertFrom("#FF094AAD");
BGS1.Offset = 0.244;
BGS2.Color = (Color)cc.ConvertFrom("#FF0745AA");
BGS2.Offset = 0.988;
BGS3.Color = (Color)cc.ConvertFrom("#FF286ED1");
BGS3.Offset = 0.5;
BGS4.Color = (Color)cc.ConvertFrom("#FF094AAD");
BGS4.Offset = 0.076;
BGS4.Offset = 0.076;
BlueG.Add(BGS1);
BlueG.Add(BGS2);
BlueG.Add(BGS3);
BlueG.Add(BGS4);
MetallicBlue.StartPoint = new Point(0.5, 0);
MetallicBlue.EndPoint = new Point(0.5, 1);
MetallicBlue.GradientStops = BlueG;
textBlock.Foreground = MetallicBlue;
textBlock.Text = "Sample";
textBlock.FontSize = 40;

Textblocks aren't added?

I'm trying to generate some UI Elements dynamically. The whole thing works, except it seems like the textblocks are invisible.
Grid pGrid = this.createPodiumGrid();
//create textblocks etc
TextBlock bTijd = new TextBlock();
bTijd.Text = currentGig.BeginTijd;
bTijd.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
bTijd.Foreground = new SolidColorBrush(Color.FromArgb(0, 0, 0, 0));
Grid.SetColumn(bTijd, 0);
Grid.SetRow(bTijd, 0);
pGrid.Children.Add(bTijd);
TextBlock pName = new TextBlock();
pName.Text = currentGig.Podium.Naam;
pName.Margin = new Thickness(20, 0, 0, 0);
pName.Foreground = new SolidColorBrush(Color.FromArgb(0, 0, 0, 0));
Grid.SetColumn(pName, 1);
Grid.SetRow(pName, 0);
pGrid.Children.Add(pName);
Image favImg = new Image();
favImg.Source = new BitmapImage(new Uri("/Images/thumb.png", UriKind.RelativeOrAbsolute));
favImg.Width = 50;
favImg.Height = 50;
favImg.HorizontalAlignment = System.Windows.HorizontalAlignment.Right;
Grid.SetColumn(favImg, 2);
Grid.SetRow(favImg, 0);
pGrid.Children.Add(favImg);
podiumStackPanel.Children.Add(pGrid);
The last image, does show on the right location. Am I missing something here? Text color is black on a white background. But I can't see the text. I'm 100% positive that the value is filled.
Change your code to the following:
bTijd.Foreground = new SolidColorBrush(Color.FromArgb(255, 0, 0, 0));
You have set the color to transparent by adding the first '0'.
pName.Foreground = new SolidColorBrush(Color.FromArgb(0, 0, 0, 0));
The first parameter of Color.FromArgb is the alpha channel. That is, the opacity. And you're setting it to 0, which explains why the TextBlock is invisible. Just set it to 255 instead:
pName.Foreground = new SolidColorBrush(Color.FromArgb(255, 0, 0, 0));
Or use the Colors enumeration:
pName.Foreground = new SolidColorBrush(Colors.Black);
You have made their Foreground transparent by setting a zero alpha value in Color.FromArgb.
Set the Foreground to Colors.Black instead, e.g.
bTijd.Foreground = new SolidColorBrush(Colors.Black);
or of course
bTijd.Foreground = new SolidColorBrush(Color.FromArgb(255, 0, 0, 0));

C# Windows Phone - Creating a round mask

I need to mask dynamically created images, so that they will be shown as circles.
Pictures can be square, but are usually rectangles... so the circle that will be shown can be taken from the center of it...so the shown circle must be inscribed in the picture and centered in the center of it.
This is the code I'm using right now:
//Setting up the image
Image image = new Image();
image.Height = 70;
image.Width = 70;
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.UriSource = new Uri("http://url-of-the-image", UriKind.Absolute);
image.CacheMode = new BitmapCache();
image.Source = bitmapImage;
image.Stretch = Stretch.UniformToFill;
image.VerticalAlignment = System.Windows.VerticalAlignment.Center;
//Setting up the mask
RadialGradientBrush opacityMask = new RadialGradientBrush();
GradientStop gs1 = new GradientStop();
GradientStop gs2 = new GradientStop();
GradientStop gs3 = new GradientStop();
gs1.Color = Color.FromArgb(255, 0, 0, 0);
gs1.Offset = 0.0;
gs2.Color = Color.FromArgb(255, 0, 0, 0);
gs2.Offset = 0.999;
gs3.Color = Color.FromArgb(0, 0, 0, 0);
gs3.Offset = 1.0;
opacityMask.GradientStops.Add(gs1);
opacityMask.GradientStops.Add(gs2);
opacityMask.GradientStops.Add(gs3);
image.OpacityMask = opacityMask;
//Showing the image
panel.Children.Add(image);
This all works fine, but when the pictures are rectangular and not square, this creates an ellipse instead of a circle... any idea on how can I force it to create a circle?
I also tried to specify some more parameters, but doesn't seem to help:
opacityMask.Center = new Point(0.5, 0.5);
opacityMask.RadiusX = 0.5;
opacityMask.RadiusY = 0.5;
Okay, today i tried again to fix this, and i came out with a solution.
It's not the best, more clean solution ever...but works :)
I basically wrapped the picture (not masked) into a StackPanel and then applied the mask to the StackPanel instead ;)
This is how it looks like (the only lines that change from the original are the the last few ones):
//Setting up the image
Image image = new Image();
image.Height = 70;
image.Width = 70;
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.UriSource = new Uri("http://url-of-the-image", UriKind.Absolute);
image.CacheMode = new BitmapCache();
image.Source = bitmapImage;
image.Stretch = Stretch.UniformToFill;
image.VerticalAlignment = System.Windows.VerticalAlignment.Center;
//Setting up the mask
RadialGradientBrush opacityMask = new RadialGradientBrush();
GradientStop gs1 = new GradientStop();
GradientStop gs2 = new GradientStop();
GradientStop gs3 = new GradientStop();
gs1.Color = Color.FromArgb(255, 0, 0, 0);
gs1.Offset = 0.0;
gs2.Color = Color.FromArgb(255, 0, 0, 0);
gs2.Offset = 0.999;
gs3.Color = Color.FromArgb(0, 0, 0, 0);
gs3.Offset = 1.0;
opacityMask.GradientStops.Add(gs1);
opacityMask.GradientStops.Add(gs2);
opacityMask.GradientStops.Add(gs3);
//Setting up the StackPanel
StackPanel sp = new StackPanel();
sp.OpacityMask = opacityMask;
//Showing the image
sp.Children.Add(image);
panel.Children.Add(sp);

LinearGradientBrush animation

I am trying to convert "wipe" animation http://learnwpf.com/post/2006/10/03/How-can-I-create-a-e2809cwipee2809d-effect-to-transition-between-two-images-in-WPF.aspx sample to use it in C#.
So I did like:
<Grid>
<Image Source="C:\Temp\WMS\Others\megan_fox_17-normal.jpg" />
<Image Source="C:\Temp\WMS\Others\Hudgens.jpg">
<Image.OpacityMask>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
<GradientStop Offset="0" Color="Black" x:Name="BlackStop"/>
<GradientStop Offset="0" Color="Transparent" x:Name="TransparentStop"/>
</LinearGradientBrush>
</Image.OpacityMask>
</Image>
<Button Content="Button" HorizontalAlignment="Left" Margin="72,288,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_1"/>
</Grid>
and
private void Button_Click_1(object sender, RoutedEventArgs e)
{
var _doubleAnimationFrontPlayer = new DoubleAnimation();
_doubleAnimationFrontPlayer.By = 1;
_doubleAnimationFrontPlayer.Duration = new Duration(TimeSpan.FromSeconds(2));
sb.Children.Add(_doubleAnimationFrontPlayer);
Storyboard.SetTargetProperty(_doubleAnimationFrontPlayer, new PropertyPath(GradientStop.OffsetProperty));
Storyboard.SetTargetName(TransparentStop, "TransparentStop");
Storyboard.SetTarget(_doubleAnimationFrontPlayer, TransparentStop);
var _doubleAnimationFrontPlayer2 = new DoubleAnimation();
_doubleAnimationFrontPlayer2.By = 1;
_doubleAnimationFrontPlayer2.Duration = new Duration(TimeSpan.FromSeconds(2));
_doubleAnimationFrontPlayer2.BeginTime = TimeSpan.FromMilliseconds(1000) ;
sb.Children.Add(_doubleAnimationFrontPlayer2);
Storyboard.SetTargetProperty(_doubleAnimationFrontPlayer2, new PropertyPath(GradientStop.OffsetProperty));
Storyboard.SetTargetName(BlackStop, "BlackStop");
Storyboard.SetTarget(_doubleAnimationFrontPlayer2, BlackStop);
sb.Completed += sb_Completed;
sb.Begin();
}
void sb_Completed(object sender, EventArgs e)
{
Debug.WriteLine("DONE");
}
But nothing happens... :(
Any clue what is missing?
THANK YOU!
P.S. I found too late the same question here WPF Translating an XAML Animation to C# Code
So th ecorrect code I found here WPF Translating an XAML Animation to C# Code
I just edited it because I found 3 errors there:
public void WipeAnimation(FrameworkElement ObjectToAnimate)
{
LinearGradientBrush OpacityBrush = new LinearGradientBrush();
OpacityBrush.StartPoint = new Point(1, 0);
OpacityBrush.EndPoint = new Point(0, 0);
GradientStop BlackStop = new GradientStop(Colors.Black, 0);
GradientStop TransparentStop = new GradientStop(Colors.Transparent, 0);
OpacityBrush.GradientStops.Add(BlackStop);
OpacityBrush.GradientStops.Add(TransparentStop);
ObjectToAnimate.OpacityMask = OpacityBrush;
this.RegisterName("TransparentStop", TransparentStop);
this.RegisterName("BlackStop", BlackStop);
Duration d = TimeSpan.FromSeconds(4);
Storyboard sb = new Storyboard() { Duration = d };
DoubleAnimation DA = new DoubleAnimation() { By = 1, Duration = d };
DoubleAnimation DA2 = new DoubleAnimation() { By = 1, Duration = d };
sb.Children.Add(DA); sb.Children.Add(DA2);
Storyboard.SetTargetName(DA, "TransparentStop");
Storyboard.SetTargetName(DA2, "BlackStop");
Storyboard.SetTargetProperty(DA, new PropertyPath("Offset"));
Storyboard.SetTargetProperty(DA2, new PropertyPath("Offset"));
sb.Begin(this);
}
Author got +1 as well! :)

Categories

Resources