Hi at present I am using a grid with Image and two Buttons for showing a custom message box in my WP7 application whose visibility is collapsed at first. All is working fine but I have to disable all the controls behind on the page when its visibility is visible. So its quite a overhead to enable/disable lots of control behind.
Is there a better solution for my requirement which are :(1) To show a message box having image and two button or textbox and (2) It should appear in the middle of page.
Thanks in advance!!
You can use built in Popup control with an attached behaviour written by Kent Boogaart, so it would behave like WPF Popup control with PlacementTarget and Placement:
<Popup b:PopupPlacement.PlacementTarget="{Binding ElementName=someElement}">
<b:Popup.PreferredOrientations>
<b:PopupOrientationCollection>
<b:PopupOrientation Placement="Top" HorizontalAlignment="Center"/>
<b:PopupOrientation Placement="Bottom" HorizontalAlignment="Center"/>
<b:PopupOrientation Placement="Right" VerticalAlignment="Center"/>
<b:PopupOrientation Placement="Right" VerticalAlignment="TopCenter"/>
</b:PopupOrientationCollection>
</b:Popup.PreferredOrientations>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0">My popup's contents</TextBlock>
<Image Grid.Row="1" .... />
</Grid>
</Popup>
See the article Silverlight Popup with Target Placement
Download a project
What I do in this situation is to add a Grid or Border to the page that has a transparent background and IsHitTestVisible = True. You can then add your image etc to the parent control (Grid/Border).
You need to make sure the parent control covers the whole page and then just center the dialog inside this control. When you toggle the visibility of the parent control then the transparent background will overlay the other controls on the page, effectively disabling them.
Here is an example. The uxMessageGrid is the parent control and the Border is the actual dialog. You then just need to make sure this is the last control added to the root element and toggle uxMessageGrid.Visibility in your code.
<Grid x:Name="uxLayoutRoot">
<Other Controls />
<Grid x:Name="uxMessageGrid"
Visibility="Collapsed"
Background="Transparent"
IsHitTestVisible="True">
<Border CornerRadius="0"
BorderThickness="1"
VerticalAlignment="Center"
HorizontalAlignment="Center"
BorderBrush="{StaticResource PhoneForegroundBrush}"
Background="{StaticResource PhoneBackgroundBrush}">
<TextBlock Margin="15"
Text="Message..."
TextWrapping="Wrap"/>
</Border>
</Grid>
</Grid>
Use the Custom Dialog box features of the Coding4Fun toolkit
http://coding4fun.codeplex.com/
The toolkit has many controls available beyond the standard Silverlight Toolkit and should more than meet your needs.
Try this one, may be it helps to you
StackPanel st = new StackPanel();
StackPanel st1 = new StackPanel();
Image image = new Image();
image.Height = 300;
image.Width = 300;
image.Source = new BitmapImage(new Uri("/PhoneApp1;component/Koala.jpg", UriKind.Relative));//Build Action=Resource
Button btnok = new Button();
btnok.Content = "Ok";
btnok.Click += new RoutedEventHandler(btnok_Click);
Button btncancel = new Button();
btncancel.Content = "Cancel";
btncancel.Click += new RoutedEventHandler(btncancel_Click);
st1.Orientation = System.Windows.Controls.Orientation.Horizontal;
st1.Children.Add(btnok);
st1.Children.Add(btncancel);
st.Children.Add(image);
st.Children.Add(st1);
ContentPanel.Children.Add(st);
Related
My goal is to attach a new image control while the application is running.
img = new System.Windows.Controls.Image();
img.Margin = new Thickness(200, 10, 0, 0);
img.Width = 32;
img.Height = 32;
img.Source = etc;
I've tried
this.AddChild(img);// says must be a single element
this.AddLogicalChild(img);// does nothing
this.AddVisualChild(img);// does nothing
It was never this difficult to add a element with forms.
How can I simply attach this new element to the main window (not another control) so that it will show up.
Solved it, I named the grid main, and from there I was able to access the children attribute and the add function
main.children.add(img);
<Window x:Class="Crysis_Menu.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded" AllowsTransparency="False" Background="White" Foreground="{x:Null}" WindowStyle="SingleBorderWindow">
<Grid Name="main">
<Button Content="Run" Height="23" HorizontalAlignment="Left" Margin="12,12,0,0" Name="btnRun" VerticalAlignment="Top" Width="151" Click="btnRun_Click" />
<TextBox Height="259" HorizontalAlignment="Left" Margin="12,40,0,0" Name="tbStatus" VerticalAlignment="Top" Width="151" />
</Grid>
</Window>
You should have only one root element under window. Adding the image using this.AddChilda adds the image as child of window, but you probably have some other child defined(Grid for example). Give a name to this child (Grid in the example) and then in the code behind add the image to the Grid
Example :
<Window>
<Grid x:Name="RootGrid">
</Grid>
</Window>
Then in the code behind use
RootGrid.Children.Add(img);
What is this in your case? You can try this.Content = image; or this.Children.Add(image);
If your this is indeed a Window, you should know that Window can have only a single child, which you put into Content. If you want several items in Window, usually you put some appropriate container (for example, Grid or StackPanel) as Window's content, and add children to it.
Vlad got the solution. I used it :
var grid = this.Content as Grid;
// or any controls
Label lblMessage = new Label
{
Content = "I am a label",
Margin = new Thickness(86, 269, 0, 0)
};
grid.Children.Add(lblMessage);
I have a Customer Pages which contains information of customer name. This page contains a StackPanel and inside this StackPanel there is a ScrollViewer and inside the ScrollViewer there is another StackPanel.
I am adding number of StackPanels dynamically. Inside the StackPanel I am adding TextBlock dynamically behind, which contains text. Then add InkPresenter to show a separation.
My problem is after adding every time when I try to use the page, it doesn't scroll. In fact if I swipe up the page goes down and come back.
XAML :
<StackPanel>
<ScrollViewer Margin="0,-20,0,0" Grid.RowSpan="2" >
<StackPanel Height="Auto" x:Name="pottilelist" >
</StackPanel>
</ScrollViewer>
</StackPanel>
StackPanel stk = new StackPanel();
stk.Name = g.id.ToString();
stk.Tap += new EventHandler<System.Windows.Input.GestureEventArgs>(Customer_Click);
TextBlock tbx = new TextBlock();
tbx.Text = g.customername;
tbx.Name = "A" + g.id.ToString();
tbx.FontSize = 36;
tbx.Tap += new EventHandler<System.Windows.Input.GestureEventArgs>(Customer_Click);
tbx.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
stk.Children.Add(tbx);
InkPresenter ink = new InkPresenter();
ink.Height = 4;
ink.Background = Brush3;
ink.Margin = new Thickness(0, 0, 0, 20);
stk.Children.Add(ink);
pottilelist.Children.Add(stk);
In one app it worked, but in another it doesn't.
Try to put the scrol viewer around the Layout Grid (main grid) that contains all page contents. I think this should solve the problem.
As long as you are using Pivot Template , just put it after the deceleration of that pivot item around the grid and it should works !
<phone:PivotItem Header="PivotItem">
<ScrollViewer>
<Grid x:Name="LayoutRoot" Background="#7F000000" >
It depends on where your stackpanel is placed inside the grid.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="100"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="1">
<ScrollViewer>
<StackPanel></StackPanel>
</ScrollViewer>
</StackPanel>
</Grid>
In above code scrollviewer will work as expected, because of the height.
If you have set the height of the position in its visual tree, then scrollviewer might not scroll.
I have solved the problem. This problem occurs when there is no height for a stackpanel or scrollviewer. Height Issue
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,
In C#, using WPF components, Is it possible to display a canvas (whose contents change at run time based on user input) at two positions on the screen? or in two windows? So basically, whatever happens in the canvas positioned at one place happens in the canvas positioned in the other place.
Do you need them both to be interactive?
If not, then you could use a VisualBrush to duplicate the Canvas to another location. The VisualBrush part won't be interactive, but it will mirror what happens on the other one.
So, there are 2 solutions :
create control containing your canvas & add them to required places and bind to your VM
use visualbrush as #Tim mentioned, example:
<Window x:Class="visualbrushmirroringstackoverflow.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<VisualBrush x:Key="MirrorBrush"
Visual="{Binding ElementName=TargetCanvas}" TileMode="None"
Stretch="None" AutoLayoutContent="False"/>
</Window.Resources>
<StackPanel>
<Button Click="Button_Click" Content="Add Random Rects" Margin="5"/>
<Border BorderThickness="1" BorderBrush="Black" Margin="5">
<Canvas x:Name="TargetCanvas" Width="100" Height="100"
Background="White" />
</Border>
<Border BorderThickness="1" BorderBrush="Black" Margin="5">
<Rectangle Width="100" Height="100"
Fill="{StaticResource MirrorBrush}" />
</Border>
</StackPanel>
handler in code behind:
private void Button_Click(object sender, RoutedEventArgs e)
{
var rnd = new Random();
var element = new Rectangle { Fill = Brushes.Black, Width = 5, Height=5 };
Canvas.SetLeft(element, rnd.Next(100));
Canvas.SetTop(element, rnd.Next(100));
TargetCanvas.Children.Add(element);
}
If you're populating and updating the Canvas through databinding, you can create a usercontrol that defines the Canvas and all of it's styles, templates etc and bind each instance of that usercontrol to the same source object. Even in different windows, because they are updating from the same object in memory they should appear synchronised.
I had a same problem where i was asked to display a canvas in other window while retaining the original canvas.
What i did and you can do is this:
Since a single child cannot have multiple parents so you can make a copy of your original by serializing them using XamlReader.Save.
Put this canvas in a ViewBox (so that it stretches to its parent). Set contents of new window as this ViewBox.
Canvas copycanvas = XamlReader.Parse(XamlWriter.Save(OriginalCanvas)) as Canvas;
ViewBox vb = new ViewBox() { Stretch.Uniform, Child = copyCanvas };
Windows newwin = new Window() { Content = vb };
newwin.ShowDialog();
I'm trying to implement "Mega Menu" style menus using WPF. To see examples of mega menus in web design, see here.
So far, I've tried creating a similar interface by using TextBlocks as the highest level of the menu, and then using the mouse hover event to display an additional window that appears positioned below the text block. This is cumbersome and inflexible, future changes would require adding/removing TextBlocks dynamically.
I have considered using the WPF Menu control, because I know the styles can be dramatically modified, but I haven't seen any way to produce multi-column layouts with the hierarchical model that the Menu control uses.
Is there a better way to do this? Am I going to have to stick with custom windows and relative positioning? Can someone point me to an example of this that has already been implemented?
Instead of using custom Windows and positioning, you could use a Popup control. Your can use the StaysOpen=false setting to have it close when the user clicks off-screen.
If you can settle for clicking a menu item instead of hovering, the following custom control will work:
[TemplatePart(Name="PART_HoverArea", Type=typeof(FrameworkElement))]
[TemplatePart(Name="PART_Popup", Type=typeof(Popup))]
public class MegaMenuItem : HeaderedContentControl
{
private FrameworkElement hoverArea;
private Popup popup;
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
// Unhook old template
if (hoverArea != null)
{
hoverArea.PreviewMouseUp -= ShowPopupOnMouseDown;
}
hoverArea = null;
popup = null;
if (Template == null)
return;
// Hook up new template
hoverArea = (FrameworkElement)Template.FindName("PART_HoverArea", this);
popup = (Popup)Template.FindName("PART_Popup", this);
if (hoverArea == null || popup == null)
return;
hoverArea.PreviewMouseUp += ShowPopupOnMouseDown;
}
private void ShowPopupOnMouseDown(object sender, MouseEventArgs e)
{
popup.PlacementTarget = hoverArea;
popup.Placement = PlacementMode.Bottom;
popup.StaysOpen = false;
popup.IsOpen = true;
}
}
You would need a style to display it - something like this. Note the PART_ template part names:
<Style TargetType="WpfApplication14:MegaMenuItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="WpfApplication14:MegaMenuItem">
<Grid>
<Border Name="PART_HoverArea" Background="#fb9c3b" BorderBrush="White" BorderThickness="0,0,1,0">
<ContentPresenter Content="{TemplateBinding Header}" />
</Border>
<Popup
Name="PART_Popup"
PlacementTarget="{Binding ElementName=HoverArea}"
>
<Border MinWidth="100" MaxWidth="400" MinHeight="40" MaxHeight="200" Background="#0d81c3">
<ContentPresenter Content="{TemplateBinding Content}" />
</Border>
</Popup>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The XAML for your menu would then be:
<StackPanel Orientation="Horizontal" VerticalAlignment="Top">
<WpfApplication14:MegaMenuItem Header="Parent 1">
<WrapPanel Margin="5">
<TextBlock Text="Put any content you want here" Margin="5" />
<TextBlock Text="Put any content you want here" Margin="5" />
<TextBlock Text="Put any content you want here" Margin="5" />
</WrapPanel>
</WpfApplication14:MegaMenuItem>
<WpfApplication14:MegaMenuItem Header="Parent 2">
<WrapPanel Margin="5">
<TextBlock Text="Put any content you want here" Margin="5" />
<TextBlock Text="Put any content you want here" Margin="5" />
<TextBlock Text="Put any content you want here" Margin="5" />
</WrapPanel>
</WpfApplication14:MegaMenuItem>
</StackPanel>
Making the menu appear on hover is much harder, because of the way Popups steal focus (you can show the menu, but you can't easily hide it if they mouse over another menu). For that a custom window might work better.
You could use a HeaderedItemsControl and swap out the Panel to suit your needs; by default it uses a StackPanel however a WrapPanel may suit you better. The pop out and mouse over behavior do not exist by default and would need to be implemented.
A more robust approach would be to leverage a custom Expander; as it provides the pop out behavior you are after and the linked to walkthrough provides the mouse over behavior.
I wonder if the Ribbon control can be retrofitted to do this? It provides tabs, labels, columns and all that.
Please use this UI design sparingly and make sure that it only opens and closes when the user specifically requests such. It's tremendously annoying when a popup mega-menu appears over a website I'm viewing, and I can't get it to close, except for when I want to click on it and it goes away.
Custom windows and relative position are essentially how the WPF Menu/MenuItem control works... but as you've found, it's non-trivial. Best bet would be to retemplate the Menu/MenuItem controls to meet your need.