How to change ImageBrush dynamically? - c#

Here is some code that does not work:
XAML:
<TextBox />
<TextBox.Background>
<ImageBrush x:Name="image_background" Stretch="Fill" TileMode="None" AlignmentX="Left" AlignmentY="Center" />
</TextBox.Background>
</TextBox>
C#: (It does not work to dynamically change image.)
image_background.ImageSource = null;
image_background.ImageSource = CreateBitmapSource(System.Windows.Media.Color.FromArgb(255, 0, 0, 0)); // Black Color
Is not changing the image, any solution?
Here is code that works fine.
private void Window_Loaded(object sender, RoutedEventArgs e)
{
// work fine
image_background.ImageSource = CreateBitmapSource(System.Windows.Media.Color.FromArgb(255, 0, 255, 0));
}
UPDATE:
System.Windows.Application.Current.Dispatcher.Invoke(
DispatcherPriority.Background,
new Action(() => image_background.ImageSource = CreateBitmapSource(System.Windows.Media.Color.FromArgb(255, 0, 255, 0))));

Related

Why window smaller than actualwidth?

I want capture window but The actual window size seems to be smaller than the figure.
this is code
<Window x:Class="FileRead.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Width="620" Height="340" >
<Grid>
<StackPanel>
<StackPanel Orientation="Horizontal">
<Button x:Name="ReadImageButton" Width="100" Height="30" Margin="10" Click="ReadImage_Click">
LoadImage
</Button>
<Button x:Name="ReadTextButton" Width="100" Height="30" Margin="10" Click="ReadText_Click">
LoadText
</Button>
<Button x:Name="CaptueScreenButton" Width="80" Height="30" Margin="10" Click="CaptueScreenButton_Click">
ScreenCapture
</Button>
<Button x:Name="CaptuerWindowButton" Width="80" Height="30" Margin="10" Click="CaptuerWindowButton_Click">
WindowCapture
</Button>
I couldn't find a problem.
private void CaptuerWindowButton_Click(object sender, RoutedEventArgs e)
{
int width = (int)this.ActualWidth;
int height = (int)this.ActualHeight;
Point point = this.PointToScreen(new Point(0, 0));
CheckLable.Content = string.Format("{0} / {1}", this.Width, this.ActualWidth);
using (Bitmap bmp = new Bitmap(width, height))
{
using (Graphics gr = Graphics.FromImage(bmp))
{
gr.CopyFromScreen( (int)point.X, (int)this.Top, 0, 0, bmp.Size);
}
bmp.Save(ImagePath + "/WindowCapture.png", ImageFormat.Png);
}
}
result image
There is always a difference of about 15 points.:
help me please.
enter image description here
The cause of your problem is that size of a window include the area that draw by OS, which was called "non-client area", usually include frame, border, drop show effect. And your calculation didn't consider that. The right code will like
var clientTopLeft = this.PointToScreen(new System.Windows.Point(0, 0));
// calculate the drop show effect offset.
var shadowOffset = SystemParameters.DropShadow ? clientTopLeft.X - Left -
((WindowStyle == WindowStyle.None && ResizeMode < ResizeMode.CanResize) ? 0 : SystemParameters.BorderWidth) : 0;
// exclude left and right drop shadow area
int width = (int)(Width - 2 * shadowOffset);
// exclude bottom drop shadow area
int height = (int)(Height - shadowOffset);
using (Bitmap bmp = new Bitmap(width, height))
{
using (Graphics gr = Graphics.FromImage(bmp))
{
gr.CopyFromScreen((int)(Left + shadowOffset),
(int)Top, 0, 0, bmp.Size);
}
bmp.Save("WindowCapture.png");
}

UWP / WinRT Generate Path from multiple rects

How I can create a custom path from two or more rectangles?
I am working with xaml / UWP and the fill color have to transparent.
Current State;
Needed State;
Currently I am using following code:
GeometryGroup path = new GeometryGroup();
path.Children.Add(new RectangleGeometry() { Rect = new Rect(0, 0, 100, 100) });
path.Children.Add(new RectangleGeometry() { Rect = new Rect(30, 30, 150, 100) });
Data = path;
<Path HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10"
Data="{Binding Data}"
Stroke="Blue" StrokeThickness="5" Opacity="1" />

Wpf Text marquee behind other element

I built an messagebar, with an animated text,
see the .gif from the animation.
Like you can see the text "fly's" in the foreground and hides the placeholder. But I need the placeholder in the foreground.
My first idea was to change the region of the animation from
doubleAnimation.To = tbInfo.ActualWidth *-1;
to
doubleAnimation.To = boLogo.ActualWidth;
but the result looks like this: version with other animation area.
How can I set the placeholder in the foreground, so that the animation "fly's" behind it?
My XAML-Code
<Canvas x:Name="canMain" HorizontalAlignment="Stretch" VerticalAlignment="Center">
<Border x:Name="boLogo" Height="40" Background="Gray" Canvas.Left="0" Canvas.Top="-20">
<Button Content="Placeholder" Width="90" />
</Border>
<TextBlock x:Name="tbInfo" Visibility="Hidden" FontSize="32" FontWeight="Bold" Padding="5" HorizontalAlignment="Stretch" VerticalAlignment="Center"></TextBlock>
</Canvas>
and the code to show the window
public void ShowWindow(string str)
{
tbInfo.Text = str;
this.Height = 39;
this.Width = SystemParameters.WorkArea.Width;
this.Left = SystemParameters.PrimaryScreenWidth - this.Width;
this.Show();
TextMarquee(20);
}
private void TextMarquee(int duration)
{
double height = canMain.ActualHeight - tbInfo.ActualHeight;
tbInfo.Margin = new Thickness(0, height / 2, 0, 0);
DoubleAnimation doubleAnimation = new DoubleAnimation();
doubleAnimation.From = canMain.ActualWidth;
doubleAnimation.To = tbInfo.ActualWidth * -1;
doubleAnimation.RepeatBehavior = RepeatBehavior.Forever;
doubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(duration));
tbInfo.BeginAnimation(Canvas.LeftProperty, doubleAnimation);
tbInfo.Visibility = Visibility.Visible;
}
Use the Panel.ZIndex:
<Canvas x:Name="canMain" >
<Border x:Name="boLogo" Panel.ZIndex="2">
<Button Content="Placeholder" Width="90" />
</Border>
<TextBlock x:Name="tbInfo" Panel.ZIndex="1"></TextBlock>
</Canvas>
https://msdn.microsoft.com/de-de/library/system.windows.controls.panel.zindex%28v=vs.110%29.aspx
Try the Grid.ZIndex:
<Grid x:Name="canMain" >
<Border x:Name="boLogo" Grid.ZIndex="2">
<Button Content="Placeholder" />
</Border>
<TextBlock x:Name="tbInfo" Grid.ZIndex="1"/>
</Grid>
Being ZIndex = "2" the most visible layer.

Displaying Image in Circle in Windows Phone

I am creating a WP (7.1+8) app, that requires me to display images inside a circle ( as in Google+ ).
I found a solution that uses a GradientBrush to accomplish the task via following code:-
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;
I want to know that what will be the performance impact if i needed to do this on large number of images, say 50.
Use clipping to display partial area of a control.
<Image Source="YouImage.jpg">
<Image.Clip>
<EllipseGeometry Center="50,50" RadiusX="50" RadiusY="50" />
</Image.Clip>
</Image>
Change the Center, RadiusX and RadiusY to your convenience.
Use the following code snippet for your requirement.
<Ellipse Height="300" Width="300">
<Ellipse.Fill>
<ImageBrush ImageSource="images/WmDev.jpg" AlignmentX="Center" AlignmentY="Center" />
</Ellipse.Fill>
</Ellipse>
Hope it Helps.
This question is already answered still if you want to see it in more detail then you could have a look here
The XAML solution will be,
<Image Source=”{Binding Converter={StaticResource ContactPictureConverter}}” Width=”48″ Height=”48″ Stretch=”Fill”
>
<Image.Clip>
<EllipseGeometry Center=”24,24″ RadiusX=”24″ RadiusY=”24″ />
</Image.Clip>
</Image>

Storyboard.SetTarget vs Storyboard.SetTargetName

Why does Storyboard.SetTargetName works but Storyboard.SetTarget does not?
Here xaml -
<Grid Grid.Row="0" ClipToBounds="True">
<X:SmartContentControl x:Name="smartContent" Content="{Binding Path=MainContent}" ContentChanging="smartContent_ContentChanging">
<X:SmartContentControl.RenderTransform>
<TranslateTransform x:Name="translateTransformNew" X="0" Y="0"/>
</X:SmartContentControl.RenderTransform>
</X:SmartContentControl>
<ContentControl Content="{Binding ElementName=smartContent, Path=LastImage}">
<ContentControl.RenderTransform>
<TranslateTransform x:Name="translateTransformLast" X="0" Y="0"/>
</ContentControl.RenderTransform>
</ContentControl>
</Grid>
Here C#
private void smartContent_ContentChanging(object sender, RoutedEventArgs e)
{
Storyboard storyBoard = new Storyboard();
DoubleAnimation doubleAnimation1 = new DoubleAnimation(0.0, -smartContent.RenderSize.Width, new Duration(new TimeSpan(0, 0, 0, 0, 500)));
DoubleAnimation doubleAnimation2 = new DoubleAnimation(smartContent.RenderSize.Width, 0.0, new Duration(new TimeSpan(0, 0, 0, 0, 500)));
doubleAnimation1.AccelerationRatio = 0.5;
doubleAnimation2.DecelerationRatio = 0.5;
storyBoard.Children.Add(doubleAnimation1);
storyBoard.Children.Add(doubleAnimation2);
Storyboard.SetTarget(doubleAnimation1, this.translateTransformLast); //--- this does not work
//Storyboard.SetTargetName(doubleAnimation1, "translateTransformLast"); -- this works
Storyboard.SetTargetProperty(doubleAnimation1, new PropertyPath(TranslateTransform.XProperty));
Storyboard.SetTarget(doubleAnimation2, this.translateTransformNew);//--- this does not work
//Storyboard.SetTargetName(doubleAnimation2, "translateTransformNew"); -- this works
Storyboard.SetTargetProperty(doubleAnimation2, new PropertyPath(TranslateTransform.XProperty));
if (smartContent.LastImage != null)
storyBoard.Begin();
}
I found answer here!
Why don't these animations work when I'm using a storyboard?
Storyboard cant animate TranslateTransform, since it is not UIElement.
This is how i do it now! :)
Storyboard.SetTarget(doubleAnimation1, this.lastImage);
Storyboard.SetTargetProperty(doubleAnimation1, new PropertyPath("RenderTransform.(TranslateTransform.X)"));
Storyboard.SetTarget(doubleAnimation2, this.smartContent);
Storyboard.SetTargetProperty(doubleAnimation2, new PropertyPath("RenderTransform.(TranslateTransform.X)"));

Categories

Resources