Keeping Window "Docked" In Same Place C#/Wpf - c#

I'm working on a windows wpf app to do fluid modeling using an open source engine called epanet. There is already an open source UI written in Pascal, we are trying to create one like it with added features and usability.
I want the app to start and have a main window with a couple tool bars and 2 separate sub-windows inside, as in the original epanet UI software (take a look at some of the screen shots in the link below). What is the best way to go about this?
http://engineering.wayne.edu/wsuwater/hydraulics/epanet.php
I tried using "popup" from this forum post:
http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/bf51e572-b41e-487b-99d0-95262899ef2c/
It was far to finicky and hard to control. Instead, I just created a new window and had it open after the MainWindow() class is loaded.
InitializeComponent();
DrawingArea Init_Canvas = new DrawingArea();
Init_Canvas.Show();
This works great, other than that the user has to manually adjust it to the right size and placement every time.
How do I go about getting it stay tidily tucked in the corner?

I'm not positive I understand the question but it seems like you need to display controls on top of one another. I too ran into problems with popups too and used this code as an alternative:
<Grid>
<Canvas Grid.Row="0" Grid.Column="0">
<TextBlock FontSize="55">One</TextBlock>
</Canvas>
<Canvas Grid.Row="0" Grid.Column="0">
<TextBlock FontSize="55">Two</TextBlock>
</Canvas>
</Grid>
Basically you set both controls to be row=0 and column=0 and they will display on top of one another. Maybe this doesn't meet your needs, but it is a nice trick.

Related

Add a Behavior to an Image

In my program I have an System.Controls.Image to which I want
to add a shaking Behavior from here Animate Image in button to shake
I copied the ShakingBehavior to my project to it's own class,
and I already have the Blend SDK.
Now I added the XAML Part to my Image
<Image Source="myImage.png" Grid.Row="{Binding Path=Row}" Grid.Column="{Binding Path=Col}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0">
<i:Interaction.Behaviors>
<local:ShakeBehavior RepeatInterval="5" SpeedRatio="3.0"/>
</i:Interaction.Behaviors>
</Image>
Now I get an error that I cannot get rid of!
(As I do not have an english VS here, I try to translate the message)
The Interaction type has no attachable Behaviors property
probably just a namespace to add (the i alias), but I cannot bring it to work
edit
More information: The Image is contained in a button, which is inside a datatemplate.
And (at best) I want to start the animation when another button in the view is clicked.
(this Behavior shall help to find the button as a hint)
Since Mohib doesn't want to, i will post the correct line that I have missed:
this one should be without those magic unprinted values that can be found in Mohibs answer.
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

ContentControl is not visible when application starts via UI Automation test, but its visible when application starts by user

We are using the prism and WPF to build application. Recently we started using UI Automation (UIA) to test our app. But some strange behavior occurred when we run UIA test. Here's simplified shell:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock
Grid.Row="0" Grid.Column="0"
Name="loadingProgressText"
VerticalAlignment="Center" HorizontalAlignment="Center"
Text="Loading, please wait..."/>
<Border
Grid.Row="0"
x:Name="MainViewArea">
<Grid>
...
</Grid>
</Border>
<!-- Popup -->
<ContentControl
x:Name="PopupContentControl"
Grid.Row="0"
prism:RegionManager.RegionName="PopupRegion"
Focusable="False">
</ContentControl>
<!-- ErrorPopup -->
<ContentControl
x:Name="ErrorContentControl"
Grid.Row="0"
prism:RegionManager.RegionName="ErrorRegion"
Focusable="False">
</ContentControl>
</Grid>
In our app, we use layers (Popup and ErrorPopup) to hide MainViewArea, to deny access to the controls. To show Popup, we use next method:
//In constructor of current ViewModel we store _popupRegion instance to the local variable:
_popupRegion = _regionManager.Regions["PopupRegion"];
//---
private readonly Stack<UserControl> _popups = new Stack<UserControl>();
public void ShowPopup(UserControl popup)
{
_popups.Push(popup);
_popupRegion.Add(PopupView);
_popupRegion.Activate(PopupView);
}
public UserControl PopupView
{
get
{
if (_popups.Any())
return _popups.Peek();
return null;
}
}
Similar to this, we show ErrorPopup over all elements of our application:
// In constructor we store _errorRegion:
_errorRegion = _regionManager.Regions["ErrorRegion"]
// ---
private UserControl _error_popup;
public void ShowError(UserControl popup)
{
if (_error_popup == null)
{
_error_popup = popup;
_errorRegion.Add(_error_popup);
_errorRegion.Activate(_error_popup);
}
}
Mistics...
When we run it as users do it (double click on app icon), we can see both custom controls (using AutomationElement.FindFirst method, or through Visual UI Automation Verify). But when we start it using UI Automation test - ErrorPopup disapears from the tree of the controls. We trying to start the application like this:
System.Diagnostics.Process.Start(pathToExeFile);
I think that we missed something. But what?
Edit #1
As #chrismead said, we tried to run our app with UseShellExecute flag set to true, but this does not help. But if we start app from cmd line, and manually click the button, Popup and ErrorPopup are visible in automation controls tree.
Thread appThread = new Thread(delegate()
{
_userAppProcess = new Process();
_userAppProcess.StartInfo.FileName = pathToExeFile;
_userAppProcess.StartInfo.WorkingDirectory = System.IO.Directory.GetCurrentDirectory();
_userAppProcess.StartInfo.UseShellExecute = true;
_userAppProcess.Start();
});
appThread.SetApartmentState(ApartmentState.STA);
appThread.Start();
One of our suggestion is when we use method FindAll or FindFirst to search the button to click, window somehow cached its UI Automation state, and does not update it.
Edit #2
We have find, that extension method of prism library IRegionManager.RegisterViewWithRegion(RegionNames.OurRegion, typeof(Views.OurView)) have some strange behavior. If we stopped use it, this solve our problem particulary. Now we able to see ErrorView and any kind of view in PopupContentControl, and application updates UIA elements tree structure. But this is not an answer - "Just stop use this feature"!
In MainViewArea we have a ContentControl, which updates it content depending on user actions, and we are able to see only the first loaded UserControl to that ContentControl.Content property. This is performed like this:
IRegionManager regionManager = Container.Resolve<IRegionManager>();
regionManager.RequestNavigate(RegionNames.MainContentRegion, this.Uri);
And if we change the view, no updates will performed in UI Automation tree - the first loaded view will be in it instead. But visually we observe another View, and WPFInspector shows it properly (its show not a UI Automation tree), but Inspect.exe - not.
Also our suggestion that window use some kind of caching is wrong - caching in UI Automation client we have to turn on explicitly, but we don't do it.
I'm sorry that I've missed some detail, that was the key to the answer. I think that it was not important thing. Anyway.
We used NavBar from DevExpress controls library for WPF. What turns out, is when NavBar is present, dynamically created views are not appears on the UI Automation tree. When remove it from the window, there was an ability to see all dynamically loaded views. What does the NavBar - still mistic for me.
Here bright example to see what happened, if NavBar is present or absent on the Window (DevExpress is required).
MainWindow.xaml:
<Window xmlns:dxn="http://schemas.devexpress.com/winfx/2008/xaml/navbar"
x:Class="Test.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"
>
<Grid Name="ContentGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<!--Comment NavBar to see dynamic control in UI Automation tree-->
<dxn:NavBarControl Name="asdasd">
<dxn:NavBarControl.Groups>
<dxn:NavBarGroup Header="asdasdasdasd" />
</dxn:NavBarControl.Groups>
</dxn:NavBarControl>
<TextBox Grid.Column="1" Name="Statictb" Text="static is visible in ui automation tree" />
<Button Grid.Row="1" Content="Create controls" Height="25" Click="Button_Click"/>
</Grid>
</Window>
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
TextBox tb = new TextBox();
Grid.SetRow(tb, 1);
Grid.SetColumn(tb, 1);
tb.Text = "dynamic is not visible, if NavBar here...";
ContentGrid.Children.Add(tb);
}
}
Edit
According to the DevExpress answer on their support site:
After a peer is created, listening of automation events may cause performance issues. We have decided to clear invocation lists of automation events to resolve it. In your specific situation, you need to disabling clearing. To do it, please set the static DevExpress.Xpf.Core.ClearAutomationEventsHelper.IsEnabled property to False in the Window constructor.
This solve the problem.
My guess is that the ContentControl's automation peer should update its children with AutomationPeer.ResetChildrenCache() after the view has been changed.
AutomationPeer.InvalidatePeer() should have the same effect (in addition to other side effects) and it is supposed to be called automatically in response to the LayoutUpdated event. You might want to check that the LayoutUpdated event is raised when the view changes.
stukselbax, try to find a sequence of keystrokes (TABs, and an ENTER most likely) to click the button that enables you to see the items. it is pretty easy to send keystrokes and i can add more in here about that if that works for you. you can always establish a tab order in your application that makes the most sense for users.
------ Update on 6/20/12 --------
Have you tried double clicking a shortcut to your app on the desktop using PInvoke to see if you can see the controls when it is opened that way? Here is a link to an example here on stackoverflow:
Directing mouse events [DllImport("user32.dll")] click, double click
Another idea: some of the controls on the app I am currently automating don't show up in the tree until a mouse click occurs on them. To accomplish this without using any hardcoded coordinates, I find something in the tree which is just (above/below/etc) the place where I need to click to get the control to appear. I then get the mouse coordinates for that item and put the mouse at a small offset from there and click. Then I can find my controls in the tree. If the app is resized, moved around, etc. this will still work since the small offset is still valid.

How can I do a context menu with logo on the left side

I've looking for 4 hours how can I do a context menu with logo. I mean something which looks like daemon tools context menu.
For these who dont know how it looks like:
Is there any option to do it in simple way in XAML?
You will have to adjust ContextMenu's control template.
Just copy the whole thing and and wrap this StackPanel in Grid or DockPanel to which you add the image:
<StackPanel ClipToBounds="True" Orientation="Horizontal" IsItemsHost="True" />
Once you understand and learn not to fear control templates, they are really not a big deal. No C# necessary, all is pure XAML.
Brief tutorial.

How can I pop a control out of it's container to make it full screen when clicked in Silverlight/Wp7?

So I have a Panorama control and the PanoramaItems are programmatically added to the control using the following template.
<UserControl>
<Grid x:Name="LayoutRoot">
<controls:PanoramaItem Name="sitePanoramaItem" Header="{Binding Name}">
<Controls:DockPanel VerticalAlignment="Stretch">
<StackPanel Orientation="Horizontal" Margin="0,10,0,0" Controls:DockPanel.Dock="Top">
<Image Source="../Images/action.png" Width="64" />
<TextBlock Text="{Binding Stats, Mode=TwoWay}" FontSize="45" Margin="15,0,0,0" />
</StackPanel>
<Grid x:Name="graphCanvas" HorizontalAlignment="Stretch" Margin="10,10,10,10"> </Grid>
</Controls:DockPanel>
</controls:PanoramaItem>
</Grid>
</UserControl>
When I click on graphCanvas what I'd like to do is sorta pop the graphCanvas out and display that fullscreen then when I click again restore it to where it was. I've been all over this site and Google and can't find anything similar to what I'm looking for.
I would still like to maintain the Panorama control functionality so that the graphCanvas is still the only one visible but you can cycle through them. Currently I have it sorta working in that I remove the Grid from the DockPanel and put it directly in the LayoutRoot while making the sitePanoramaItem collapsed. However, it's not fullscreen as the Panorama name is still visible (I guess I could hide that as well...) When I put the graphCanvas back int he DockPanel the size of the canvas is all screwed up.
I was hoping there was a simpler way.
Is it even possible?
It is possible to create the UI you describe but it's not going to be simple. You're on the right track with removing it in code and adding it the LayoutRoot and making the Panorama hidden. However you would have to code the scrolling behavior yourself and that is going to be quite tricky - especially making it feel the way to panorama does.
One trick you could try is actually layer a PivotControl on top of your Panorama and have it be collapsed by default. Also edit it's template to remove all default content eg: remove the header control, set margins to 0, etc). Then when you want to go full screen you can remove all the graphCanvases from the Panorama items and and add them to new PivotItems in the PivotControl. Then hide the Panorama and show the Pivot. This will give you scrolling capability for free and the illusion of full screen.
Having said all that I'm not sure I would recommend this. The more common approach would be to simply be to navigate to another page when the user selects an item and handle the full screen aspects there (possibly using the Pivot control again for scrolling). And when you want to leave "fullscreen" mode simply navigate back to the first page. Handling Tombstoning of the fullscreen state will be much easier with this approach for one thing.
You can try making the graphCanvas a Page and putting it in a different XAML. Then add a frame (name it InnerFrame for example) in the same place where you have the graphCanvas right now and navigate to that page with InnerFrame. When the frame is clicked, you navigate with the RootFrame of the app to your graphCanvas page. When you decide to close it, just navigate back with the RootFrame.
Hope it's clear enough :)
Edit:
Navigation in WP7 works very similar as the standard navigation in Silverlight 4, but it's a bit more restrictive. Just throw a PhoneApplicationFrame in your XAML like this:
<phone:PhoneApplicationFrame x:Name="Frame" />
This is basically the same as a Silverlight frame. All the pages you create inherit from PhoneApplicationPage by default, so they can be showed in a frame without any changes.
Your whole application actually runs on a PhoneApplicationFrame. If you take a look at your App class you will see this:
public PhoneApplicationFrame RootFrame { get; private set; }
Here's the MSDN documentation for the navigation system on WP7

WP7 App: Too large page

I have created a small WP7 app which contains one page which is dynamically filled with content. But it goes out of viewable area. Emulator doesn't scroll the page when I click-hold-move on the screen. How do I make it scroll when needed?
One simple option is to drop the content you require inside a ScrollViewer, so for example adding a large TextBlock as so:
<ScrollViewer Name="scrollViewer" ScrollViewer.HorizontalScrollBarVisibility="Visible" >
<TextBlock Height="30" Name="textBlock" FontSize="24"
Text="This is a long block of text which wont fit in the available area" />
</ScrollViewer>
Obviously, in most cases you will want to drop a container control such as Grid or StackPanel into the ScrollViewer and place all your other controls in there.
That said, I'm wondering if you are actually looking for some of the standard WP7 Metro look and feel controls such as the Panorama and Pivot Controls which are available in the latest dev tools - follow that link for full details.

Categories

Resources