wpf busyindicator not showing up - c#

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.

Related

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;
}

Working with elements inside a control that is bound to a collection

I have an ObservableCollection<string> that is bound to an ItemsControl whose template is just a Button. The content of this button are 2 TextBlock. I'm trying to use the PreviewMouseRightButtonUp event of the button to toggle the visibility of one of the textblocks, but without being able to use xaml names for elements in the template I'm hitting a wall. Is there a way of getting to the button's content elements via sender in that preview event, or some other way of doing this? This is related to a previous question I had that didn't quite get a usable answer (probably due to my explanation, hence this simplified example). It seems to me that what should happen is I should make a control based off button that adds a property for this toggle, but that is basically what I thought I had in the previous question that wasn't working. I feel like a property and trigger is what most would say is the right way to go?
xaml:
<ItemsControl x:Name="iC" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button PreviewMouseRightButtonUp="Button_PreviewMouseRightButtonUp">
<DockPanel>
<TextBlock Text="normal" DockPanel.Dock="Top"/>
<TextBlock Text="{Binding}" DockPanel.Dock="Top" Visibility="Collapsed"/>
</DockPanel>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
code behind:
ObservableCollection<string> x = new ObservableCollection<string>();
public MainWindow()
{
x.Add("1");
x.Add("2");
InitializeComponent();
iC.ItemsSource = x;
}
If you name the hidden text block "secondTextBlock", then this should work:
private void Button_PreviewMouseRightButtonUp(object sender, MouseButtonEventArgs e)
{
DockPanel dockPanel = (DockPanel)((Button)sender).Content;
TextBlock text = (TextBlock)LogicalTreeHelper.FindLogicalNode(dockPanel, "secondTextBlock");
if (text != null)
{
text.Visibility = Visibility.Visible;
}
}
Regarding your comment below: yes, multiple instances of "secondTextBlock" will be created. See the Snoop screenshot below. But these multiple instances are OK; they do not have any negative impact.

Adding Animation to panels when they are made visible in WPF

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,

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

How click a TextBlock in DataTemplate?

This is my XAML code:
<ListBox ItemsSource="{Binding}" Name="listBox">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<StackPanel Width="370">
<TextBlock Text="{Binding AuthorName}" x:Name="author" MouseEventLeftDown="click"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
And the Click Handler
private void click(object sender, RoutedEventArgs e)
{
if(author.Text.Equals("Hi"))
{
// Do Something Special
}
}
The error is:
Error: The name 'author' does not exist in the current context
But I don't understand what is causing this error or why it is occurring.
Your TextBlock with the Name author doesn't exist in the scope of your click handler because it's in a DataTemplate. What's happening is that the author TextBlock is created once for every one of your data items (Presumably an Author class or a Book class of some kind), so you literally can have dozens of controls named author.
You are better off casting your sender in your click handler to a text box and then checking its text property. Something like this:
private void click(object sender, RoutedEventArgs args)
{
var textBox = sender as TextBox;
if(textBox == null)
return;
if(textBox.Text.Equals("hi"))
{
// Do Something Crazy!
}
}
It's probably better to use a UI element designed for touch, such as a HyperlinkButton or a Button. You can style these any way you would like to - especially if you use Expression Blend - but it is good design to include some visual feedback about the Touch.
Also - I'm not sure about your == code - you're comparing the sender (a UI element) against some string expression?
First off, your TextBlock is defined in a DataTemplate; try x:Name instead of Name on your TextBlock.
Secondly it might be quite tricky to click your TextBlock since you will have to press an exact pixel in your TextBlock. To make it easier to click your TextBlock you might want to put a Background on your TextBlock, so it will be a lot easier to click. You can even make the background transparent:
Background="Transparent"
use the gesture listener for create an event handler like "tap" or double" or whatever.
Use this...
private void click(object sender, RoutedEventArgs e)
{
var author = (TextBlock)sender;
if (author.Text.Equals("Hi"))
{
// Do Something Special
}
}

Categories