How can I find the position of a StackPanel after it has been animated?
I have a button which slides the stackpanel to the left. But if I want it to slide to the left again, the animation does not work.
Nevermind. I found out how to do this...
private Storyboard SlideEffect(UIElement controlToAnimate, double positionToMove)
{
//Get position of stackpanel
GeneralTransform gt = controlToAnimate.TransformToVisual(gridWrapper);
Point p = gt.Transform(new Point(0, 0));
//add new storyboard and animation
Storyboard sb = new Storyboard();
DoubleAnimation da = new DoubleAnimation();
da.To = p.X + positionToMove;
Storyboard.SetTarget(da, controlToAnimate);
Storyboard.SetTargetProperty(da, new PropertyPath("(controlToAnimate.RenderTransform).(TransformTranslate.X)"));
sb.Children.Add(da);
return sb;
}
private void btnNext_Click(object sender, RoutedEventArgs e)
{
SlideEffect(spCarousel, -200).Begin();
}
Related
I am using a FrameworkElementFactory as the following code in my WPF program:
FrameworkElementFactory txt1 = new FrameworkElementFactory(typeof(TextBox));
I tried to programmatically focus on this FrameworkElementFactory and also tried it with VisualTreeHelper.HitTest. Is there any way to focus on *txt1 * like txt1.Focus or HitTest ?
I created it on Listview and filled in its columns programmatically. And design this Listview according to the following codes:
for (int x = 0; x <= obj.ClmnDegerler.Length - 1; x++)
{
var GridViewColumn1 = new GridViewColumn();
txt1 = new FrameworkElementFactory(typeof(TextBox));
txt1.SetValue(TextBox.HeightProperty, 20.0);
txt1.SetValue(TextBox.WidthProperty, clmnwidth);
dataTemplate = new DataTemplate();
dataTemplate.VisualTree = txt1;
GridViewColumn1.CellTemplate = dataTemplate;
this.UGridview1.Columns.Add(GridViewColumn1);
}
And I created a button by xaml and when I want to click the button I want to focus on txt1
private void Button_Click(object sender, RoutedEventArgs e)
{
//txt1.Focus(); not working
}
I need that if my pop up window appear (after click) , the main window brightness has to decrease, maybe someone know how to do it?
Example:
EDIT: I create canvas, but do not know how to use it, brightness need decrease then pop up appear.
code:
private void sample_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
string path1 = System.AppDomain.CurrentDomain.BaseDirectory + "../../loader_bg.png";
string path2 = System.AppDomain.CurrentDomain.BaseDirectory + "../../loader.gif";
ImageBrush myBrush = new ImageBrush();
Image image = new Image();
image.Source = new BitmapImage(
new Uri(path1));
myBrush.ImageSource = image.Source;
Image ima = new Image();
MediaElement gif = new MediaElement();
ima.Source = new BitmapImage(new Uri(path1));
gif.Source=new Uri(path2);
gif.Height = 72;
gif.Width = 72;
var pop = new Popup
{
IsOpen = true,
StaysOpen = false,
AllowsTransparency = true,
VerticalOffset = 350,
HorizontalOffset = 700,
Height = 128,
Width = 128,
};
Canvas c=new Canvas();
c.Background=Brushes.Black;
c.Opacity = 0.6;
Grid p = new Grid();
p.Background = myBrush;
//p.Children.Add(ima);
//p.Children.Add(c);
p.Children.Add(gif);
pop.Child = p;
}
}
EDIT 2:
I have the same question only my code is change. Now I created new xaml.cs for pop up window, and try to achieve the same purpose, but I do not get the same (I talk about brightness decrease).
Its my new xaml.cs :
namespace uploader
{
/// <summary>
/// Interaction logic for PopupPanel.xaml
/// </summary>
public partial class PopupPanel : UserControl
{
private Popup _currentPopup;
public PopupPanel()
{
InitializeComponent();
string path1 = System.AppDomain.CurrentDomain.BaseDirectory + "../../loader_bg.png";
string path2 = System.AppDomain.CurrentDomain.BaseDirectory + "../../loader.gif";
ImageBrush myBrush = new ImageBrush();
Image image = new Image();
image.Source = new BitmapImage(new Uri(path1));
myBrush.ImageSource = image.Source;
MediaElement gif = new MediaElement();
gif.Source=new Uri(path2);
gif.Height = 72;
gif.Width = 72;
_currentPopup = new Popup
{
StaysOpen = false,
AllowsTransparency = true,
VerticalOffset = 350,
HorizontalOffset = 700,
Height = 128,
Width = 128,
};
Overlay.Visibility = Visibility.Visible;
_currentPopup.Closed += PopupClosing;
_currentPopup.IsOpen = true;
Grid p = new Grid();
p.Background = myBrush;
p.Children.Add(gif);
_currentPopup.Child = p;
}
private void PopupClosing(object sender, EventArgs e)
{
_currentPopup.Closed -= PopupClosing;
_currentPopup = null;
Overlay.Visibility = Visibility.Collapsed;
}
}
}
My Mainwindow.xaml.cs:
namespace uploader
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void sample_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
PopupPanel pop = new PopupPanel();
}
...
I do this in all my WPF applications by using a Canvas with black background and opacity
Example:
<Window>
<Grid>
<!--Main content-->
<UserControl/>
<Grid>
<Canvas Background="Black" Opacity="0.6"/>
<!--Overlay content-->
<UserControl VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</Grid>
</Window>
Using your current code, you will need to handle the visibility of the Canvas overlay.
It's easier to to have it defined within your XAML as shown below:
<Window>
<Grid>
<!--Main content-->
<UserControl/>
<Grid>
<Canvas x:Name="Overlay"
Background="Black"
Opacity="0.6"
Visibility="Collapsed"/>
<!--Overlay content-->
<UserControl VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</Grid>
</Window>
Then, in your code-behind you can set the visibility before the popup opens, and when it closes:
Popup _currentPopup;
private void sample_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
...
_currentPopup = new Popup
{
StaysOpen = false,
AllowsTransparency = true,
VerticalOffset = 350,
HorizontalOffset = 700,
Height = 128,
Width = 128
};
Overlay.Visibility = Visibility.Visible;
_currentPopup.Closed += PopupClosing;
_currentPopup.IsOpen = true;
}
private void PopupClosing(object sender, EventArgs e)
{
_currentPopup.Closed -= PopupClosing;
_currentPopup = null;
Overlay.Visibility = Visibility.Collapsed;
}
Note, that I am using a local variable to keep a reference to the popup. This is so that I can un-subscribe from the Closing event (helps prevent memory leaks)
I want to set an image as background by clicking the ctrl button?
Any one have ideas? please revert me ASAP.
Thanks in advance.
On button click event apply the following code
ImageBrush myBrush = new ImageBrush();
myBrush.ImageSource =
new BitmapImage(new Uri(#"Image Path"));
this.Background = myBrush;
You can replace the this with your control name
You can try the following code:
private void button1_Click(object sender, RoutedEventArgs e)
{
BitmapImage imageSource = new BitmapImage(new Uri(#"Path/to/image.jpg"));
ImageBrush brush = new ImageBrush();
brush.ImageSource = imageSource;
grid.Background = brush;
}
I am animating a TextBlock. In 60 seconds, it increases FontSize from 8pt to 200pt. Everything is working fine, except that my animation is moving up and down a bit as the text grows. Why is this happening and is it possible to avoid this?
I have a very simple XAML file:
<Window x:Class="Timer.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="800"
Height="500"
Title="MainWindow"
Loaded="Window_Loaded">
<Grid>
<TextBlock
Name="TimerTextBlock"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Text="00h : 00m : 00.000s" />
</Grid>
</Window>
And equally simple code-behind:
public partial class MainWindow : Window
{
private const string timerFormat = "{0:hh'h : 'mm'm : 'ss'.'fff's'}";
private DispatcherTimer dispatcherTimer;
private DateTime targetTime;
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
targetTime = DateTime.Now.AddSeconds(60);
double totalTime = targetTime.Subtract(DateTime.Now).TotalMilliseconds;
DoubleAnimation animation = new DoubleAnimation();
animation.From = TimerTextBlock.FontSize;
animation.To = 200;
animation.Duration = new Duration(targetTime.Subtract(DateTime.Now));
TimerTextBlock.BeginAnimation(TextBlock.FontSizeProperty, animation);
dispatcherTimer = new DispatcherTimer();
dispatcherTimer.Interval = TimeSpan.FromMilliseconds(1);
dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
dispatcherTimer.Start();
}
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
if (DateTime.Compare(targetTime, DateTime.Now) > 0)
{
TimerTextBlock.Text =
string.Format(timerFormat, targetTime.Subtract(DateTime.Now));
}
}
}
Thank you for all the clarifications.
Your vertical jumping problem is due to font rendering rounding. Specifically, WPF will avoid subpixel font height in order to enable font smoothing. One way to avoid this is to convert your text into a path geometry and then use a scale transform to animate it.
Here is an alternate version of your example without the jumping. The new XAML is:
<Grid>
<Path Name="Path" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
and the new code when you load the window:
SetText("");
var transform = new ScaleTransform(1, 1);
Path.LayoutTransform = transform;
var animationX = new DoubleAnimation(1, 10, new Duration(TimeSpan.FromSeconds(60)));
transform.BeginAnimation(ScaleTransform.ScaleXProperty, animationX);
var animationY = new DoubleAnimation(1, 10, new Duration(TimeSpan.FromSeconds(60)));
transform.BeginAnimation(ScaleTransform.ScaleYProperty, animationY);
and a new method to set the text that is anmiated:
private void SetText(string text)
{
var formatted = new FormattedText(text, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface("Lucida Console"), 12, Brushes.Black);
Path.Data = formatted.BuildGeometry(new Point(0, 0));
Path.Fill = Brushes.Black;
}
and you have call SetText from your timer event handler.
Note that to avoid horizontal jumpiness, you have to use a fixed-length text string and a constant-width font.
I have a grid, a window root element. I want to apply an animation which would change it's background color from white to green in 5 seconds. Here's what I did:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
ColorAnimation animation;
animation = new ColorAnimation();
animation.From = Colors.White;
animation.To = Colors.Green;
animation.Duration = new Duration(TimeSpan.FromSeconds(5));
rootElement.BeginAnimation(Grid.BackgroundProperty, animation);
}
The code doesn't work. Nothing is changing. Where am I making a mistake? Thanks.
Solved!
private void Window_Loaded(object sender, RoutedEventArgs e)
{
SolidColorBrush rootElementBrush;
ColorAnimation animation;
rootElementBrush = this.FindResource("RootElementBrush") as SolidColorBrush;
// Animate the brush
animation = new ColorAnimation();
animation.To = Colors.Green;
animation.Duration = new Duration(TimeSpan.FromSeconds(5));
rootElementBrush.BeginAnimation(SolidColorBrush.ColorProperty, animation);
}
Here's an explanation:
My initial mistake was that I wanted to change the Grid.BackgroundProperty by assigning colors to it, but it accepts brushes instead... apples and oranges! So, I created a SolidColorBrush static resource and named it rootElementBrush. In XAML, I set Grid rootElement's background property to that static resource. And finally, I modified the animation, so now it changes the color for that SolidColorBrush. Easy!
Give this a try:
<ColorAnimation
Storyboard.TargetName="PlayButtonArrow"
Storyboard.TargetProperty="Fill.Color"
From="White"
To="Green"
Duration="0:0:5.0"
AutoReverse="False"/>
You do not need to set the StaticResource, just use the Storyboard.
private void Window_Loaded(object sender, RoutedEventArgs e)
{
// Animate the brush
ColorAnimation animation = new ColorAnimation();
animation.To = Colors.Green;
animation.Duration = new Duration(TimeSpan.FromSeconds(5));
Storyboard.SetTargetProperty(animation, new PropertyPath("(Grid.Background).(SolidColorBrush.Color)", null));
Storyboard storyboard = new Storyboard();
storyboard.Children.Add(animation);
storyboard.Begin(rootElement);
}