Adding Animation to panels when they are made visible in WPF - c#

I am creating an application in WPF and the window has one main grid with 3 rows. There are 3 buttons in the 3rd row and on the click of each button, a panel is displayed in the 2nd grid row. I achieved this by setting the visibility option of the panels. However, now I would like to add an effect/animation as the panels become visible. I don't know where to start, so kindly help.
My xaml code is similar to this
<Window>
<Grid>
<!-- 3row definitions -->
<Grid Grid.Row="0"> </Grid>
<Grid Name="panel1" Grid.row="1" Visibility="Hidden"></Grid>
<Grid Name="panel2" Grid.row="1" Visibility="Hidden"></Grid>
<Grid Name="panel3" Grid.row="1" Visibility="Hidden"></Grid>
<Grid Grid.Row="2"></Grid>
</Grid>
</Windows>
Xaml.cs code to change the visibility is similar to this
private void Image_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
panel1.Visibility = System.Windows.Visibility.Visible;
panel2.Visibility = System.Windows.Visibility.Hidden;
panel3.Visibility = System.Windows.Visibility.Hidden;
}

this can be done using expression studio, in expression blend open your wpf projects, there you can add animations to your wpf controls, you also need to start and stop animation when your application launches,
http://www.youtube.com/watch?v=JpGvl1TayAQ
here is a video tutorial, you can get more tutorials by googling it,

Related

how to delete a selected text box that was created at run time

I have a WPF application that has two buttons- Add and Remove. The add button adds text boxes in a specific grid in the gui at the run time programmatically and text box names will be assigned at runtime too. I want the delete button to delete the selected text box that was generated at the run time from the gui. I am not aware of a way to delete the text box unless I know the text box name and I am not sure which way to go regarding this. I would appreciate even a little guidance. I am very new to WPF and I am sure I should be missing some obvious.
Thanks in advance.
If you're using MVVM, (which you should be in WPF), you can do this:
In the ViewModel, expose a public ObservableCollection<T> that would contain the business objects (e.g. a User) that you need to show TextBoxes for.
In the UI, add an ItemsControl and bind it to your ObservableCollection.
Define a DataTemplate that translates the business objects into TextBoxes and binds TextBox properties to business objects members.
Implement Add and Remove RelayCommands in the ViewModel.
Bind your Add and Remove buttons with these commands.
This will save you from the hectic of walking the visual tree and finding appropriate textboxes etc.
Here is a basic demo to add and remove elements in/from Grid :
XAML:
<Window x:Class="TabControl.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TabControl"
Title="MainWindow" Height="300" Width="300"
xmlns:Interact="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}"
>
<ScrollViewer VerticalScrollBarVisibility="Visible">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<Button Content="Add New Box" Click="Button_Click" />
<Button Content="Remove Selected Box" PreviewMouseLeftButtonDown="Button_PreviewMouseLeftButtonDown" />
</StackPanel>
<Grid x:Name="mygrid">
</Grid>
</StackPanel>
</ScrollViewer>
Events:
private void Button_Click(object sender, RoutedEventArgs e)
{
var textBox=new TextBox();
mygrid.RowDefinitions.Add(new RowDefinition());
textBox.Name = "textBox" + mygrid.RowDefinitions.Count;
textBox.SetValue(Grid.RowProperty, mygrid.RowDefinitions.Count);
mygrid.Children.Add(textBox);
}
private void Button_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var focusedElement = Keyboard.FocusedElement;
if (focusedElement is TextBox)
{
mygrid.Children.Remove(focusedElement as UIElement);
}
}
Output
Above is very basic WPF approach you can take, However i very much recommend you to look into MVVM pattern to easy to logic separation and flexibility (like #dotNEt suggested in his answer).

Is this concept of a button containing a textbox possible?

Recently I had been looking for a way to make the tabs in a TabControl editable and came across This example on telerik's website. That did exactly what I wanted but it got me thinking about a similar usage for buttons. I was wondering if it would be possible to use something like that and make a button that would show a textbox instead of the content presenter when say, you right click the button? I tried to make something like this work but so far have only ended up with a blank button.
<Button x:Name="SB" Height="222" Width="222" Click="SB_Click">
<ContentControl.ContentTemplate>
<DataTemplate>
<local:SuperButton Content="{Binding Path=x, Mode=TwoWay}"/>
</DataTemplate>
</ContentControl.ContentTemplate>
</Button>
Where x is a string variable and using the code behind from the link above (with a class name change, of course).
edit: This button will be in an itemscontrol, so I don't think naming the inner elements in xaml will work, but I do like the ease of Wolfgang's answer.
The WPF Content Model is really flexible and allows literally anything inside anything.
This is perfectly valid XAML:
<Button>
<TextBox/>
</Button>
Or even:
<Button>
<MediaElement Source="C:\Videos\WildLife.wmv"/>
</Button>
You can simply host a (e.g.) label (TextBlock) with the text AND a TextBox inside the Button and set their Visiblity properties.
That way, if you right click the button, the TextBox shows up.
<Button>
<Grid>
<TextBox Text=normal button caption" x:Name="label" />
<TextBox
x:Name="textbox"
Text="visible on right click"
MouseRightButtonDown="HandleRightClick"/>
</Grid>
</Button>
And then in your C# code create an event handler to set the Visiblity correctly.
void HandleRightClick(object sender, MouseButtonEventArgs e)
{
label.Visibility = Visibility.Collapsed;
textBlock.Visibility = Visibility.Visible;
}

Silverlight app freezes when simply adding a textblock to the layoutroot

I cannot understand why in the hell this simple silverlight application freezes up. Here is the code:
namespace test
{
public partial class MainPage : UserControl
{
TextBlock txtword;
public MainPage()
{
InitializeComponent();
txtword = new TextBlock();
txtword.Text = "TEST";
LayoutRoot.Children.Add(txtword);
}
private void button1_Click(object sender, RoutedEventArgs e)
{
txtword.Text = "SuperDuper";
}
}
}
After the textblock is added to the layoutroot if you try to hover or click on the button you can tell that the app has frozen for some reason. Any idea what is going on here??
If i add the text block in the XAML i am able to change its text property in the button click. LayoutRoot.Children.Add() is causing the app to freeze..
From reading your comments it seems the XAML in MainPage.xaml is something like the following:
<Grid x:Name="LayoutRoot" Background="White">
<Button Content="Do stuff" Click="Button_Click" />
</Grid>
After adding the TextBlock, either in code or in XAML, you effectively end up with the following:
<Grid x:Name="LayoutRoot" Background="White">
<Button Content="Do stuff" Click="Button_Click" />
<TextBlock Text="TEST" />
</Grid>
Your Grid doesn't specify any ColumnDefinitions or RowDefinitions, so you have a 1 × 1 grid with all child controls of the Grid given the entire width and height of the grid.
As neither your Button nor your TextBlock specify a z-index value (using Canvas.ZIndex), their z-order is defined by their position within the grid's Children. The TextBlock comes after the Button, so it is the one that is 'on top'.
The TextBlock may contain only a tiny amount of text, but the TextBlock itself will still fill the Grid. TextBlocks do not automatically resize to fit the text they contain and nothing else. Your Button appears not to work because the TextBlock is on top of it and receives all of the mouse events. TextBlocks are static controls that do nothing in response to any mouse event, and this should explain why your app is appearing to freeze.
Setting the HorizontalAlignment and/or VerticalAlignment of the TextBlock to a value other than Stretch stops the TextBlock being given the entire width and height of the Grid and allows the Button to receive mouse events.

Alternate ways to display forms inside a Grid row in WPF

The WPF application I've created contains a Grid with 3 rows. I have a set of buttons in the 3rd row. On Clicking the Buttons, the forms are displayed in the 2nd row of the Grid. However What I've done is quite messy because I've created all the form contents in the same window and have set the visibility to Hidden.
sample code:
<Grid Name="panel1" Grid.Row="1" Visibility="Hidden">
//contains a lot of textblocks,buttons and images
</Grid>
<Grid Name="panel2" Grid.Row="1" Visibility="Hidden">
//contains a lot of textblocks,buttons and images
</Grid>
<Grid Name="panel3" Grid.Row="1" Visibility="Hidden">
//contains a lot of textblocks,buttons and images
</Grid>
My xaml Code looks like this:
private void Image_MouseLeftButtonDown_1(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
panel1.Visibility = System.Windows.Visibility.Hidden;
panel2.Visibility = System.Windows.Visibility.Visible;
panel3.Visibility = System.Windows.Visibility.Hidden;
}
This approach looks really messy as I've included all the code in the Main Xaml file.
Need some alternate ways to do this. Kindly help.
Create a method like this
private void VisibilityManager(Grid grd)
{
new List<Grid>(){ panel1, panel2, panel3}
.ForEach(x => x.Visibility = Visibility.Hidden);
grd.Visibility = Visibility.Visible;
}
and call it like this
VisibilityManager(panel1);
for making panel1 visible and all other hidden.
In future if you have to increase your grids just make changes inside this method.
You could style a tabcontrol and switch the tab, you could use a contentcontrol and create a binding to the content you want to show. You could also use a databinding (depends on what you want to display) and use a template selector... there are many ways to solve that problem. Just tell a bit more what your contents look like

wpf busyindicator not showing up

I have a wpf busy indicator like this on my window:
<Grid><Controls1:BusyIndicator x:Name="busyIndicator2" IsBusy="False" Content="Please wait....." Visibility="Hidden"/>
</Grid>
And in the button click I m trying to set the visiblity,isBusy property of indicator to true and visible.
void button_click(object sender, RoutedEventArgs e)
{
busyIndicator2.Visibility = System.Windows.Visibility.Visible;
busyIndicator2.IsBusy = true;
}
but the indicaotr is not showing up.
Any idea why?
I've always wrapped other wpf content with the BusyIndicator, it then shows up centered over that content.
<BusyIndicator...>
<Grid>....</Grid>
</BusyIndicator>
Try wrapping your layout control in the BusyIndicator and see if that does what you are after.
Where is the BusyIndicator defined? For example, if your XAML looks like:
<Grid>
<BusyIndicator ...>
</BusyIndicator>
<ListBox ...>
</ListBox>
</Grid>
You'll never see the BusyIndicator because it's behind the ListBox. I would recommend using the BusyIndicator as suggested by Chris, otherwise, make sure it's not inadvertently behind other visuals.

Categories