WPF: Move control into new window - wpf

I have a control that placed into a custom panel. Into view model exist a boolean variable IsStandAlone. I wish when IsStandAlone is true that this control will be in new window.
I do this on setting IsStandAlone to true:
var window = new Window();
window.Content = this;
window.Closed += (s, ea) =>
{
window.Content = null;
ViewModel.IsStandAlone = false;
}
window.Show();
It's work good when i set IsStandAlone true but when i close the window control doesn't appear in the panel.

Like this?
...
If(IsStandAlone){
var newWindow = new MyNewWindow();
newWindow.Show();
}
...

Related

Transparent control not capturing mouse events

I have a window with a transparent background (not null). Inside that window, I have a user control, also with a transparent background.
The window receives mouse events, but the user control does not.
If I change the background of the user control from Transparent to #01000000, then the user control starts to receive mouse events. However, controls hosted within the user control (which are themselves visible) never receive mouse events, regardless of the user control's background.
Any ideas?
There must be something handling the event or you have some configuration issue, since it works ok for me: http://share.linqpad.net/ijx3vb.linq. (Get Linqpad free.)
var t = new TextBlock() { Text = "test" };
var uc1 = new UserControl() { Background = new SolidColorBrush(Colors.Transparent) };
uc1.MouseEnter += (s, args) => { t.Text = "UC1"; };
var uc2 = new UserControl() { Background = new SolidColorBrush(Color.FromArgb(01, 00, 00, 00)) };
uc2.MouseEnter += (s, args) => { t.Text = "UC2"; };
var g = new Grid();
g.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto });
g.RowDefinitions.Add(new RowDefinition());
g.RowDefinitions.Add(new RowDefinition());
g.Children.Add(t);
g.Children.Add(uc1);
g.Children.Add(uc2);
Grid.SetRow(t, 0);
Grid.SetRow(uc1, 1);
Grid.SetRow(uc2, 2);
PanelManager.DisplayWpfElement(g);

Print WPF grid is cropped

I found function to print content of Wpf grid but the print is cropped.
Can anybody know why?
the function:
private void PrintTest()
{
FlowDocument document;
Window window;
CreateWindowToPrint(out document, out window);
PrintDialog printDialog = new PrintDialog();
window.Show();
IDocumentPaginatorSource dps = document;
if (printDialog.ShowDialog() == true)
{
printDialog.PrintDocument(dps.DocumentPaginator, "test");
}
}
and:
private void CreateWindowToPrint(out FlowDocument document, out
Window window)
{
document = new FlowDocument { };
var test = new PrintedTest() { DataContext = this.DataContext };
document.Blocks.Add(new BlockUIContainer { Child = test });
window = new Window {Content = document, Visibility = System.Windows.Visibility.Hidden };
}
The UserControl PrintedTest contains my grid.
I don't really have much experience with printing in WPF but I thought I would give it a try.
I could reproduce your problem, and I could not solve it so far.
But In my research I have found an alternative, which is more simple to print the Grid:
var printDialog = new PrintDialog();
var result = printDialog.ShowDialog();
if (result.HasValue && result.Value)
{
var testControl = new PrintedTest() { DataContext = this.DataContext };
printDialog.PrintVisual(testControl, "My WPF printing a DataGrid");
}
Instead of sending the PrintTest you could actually just send directly the grid.

How can I pause a storyboard?

This seems like it should be a no-brainer, but I can't get a WPF storyboard to pause. I call Pause and nothing happens -- it keeps right on animating.
Here's a repro case: a button that animates its width. If you click the button, it calls Pause on the storyboard. I would expect that, as soon as I click the button, its width should stop changing; instead its width keeps right on animating as if I never called Pause.
NameScope.SetNameScope(this, new NameScope());
var storyboard = new Storyboard();
var button = new Button { Content = "Pause", Name = "pause" };
this.Content = button;
RegisterName(button.Name, button);
var animation = new DoubleAnimation(0, 200, TimeSpan.FromSeconds(5));
Storyboard.SetTargetName(animation, button.Name);
Storyboard.SetTargetProperty(animation,
new PropertyPath(FrameworkElement.WidthProperty));
storyboard.Children.Add(animation);
button.Click += (sender, e) => { storyboard.Pause(this); };
storyboard.Begin(this);
From what I understand of the docs, I should call the Pause(FrameworkElement) overload with the same parameter I passed to Begin, hence the Pause(this) above. But I've also tried storyboard.Pause(), with no change in behavior. I also tried storyboard.Pause(button) just for the heck of it, again with no effect. I would have tried storyboard.Pause(storyboard) and storyboard.Pause(animation) just to exhaust the possibilities, but neither one compiles -- it wants a FrameworkElement (or FrameworkContentElement).
How do I get the storyboad to pause?
I don't know why you are using that weired SetNameScope etc. Clearing your code i could make it work:
//NameScope.SetNameScope(this, new NameScope());
var storyboard = new Storyboard();
var button = new Button { Content = "Pause", Name = "pause" };
this.Content = button;
//RegisterName(button.Name, button);
var animation = new DoubleAnimation(0, 200, TimeSpan.FromSeconds(5));
Storyboard.SetTarget(animation, button);
Storyboard.SetTargetProperty(animation,
new PropertyPath(FrameworkElement.WidthProperty));
storyboard.Children.Add(animation);
button.Click += (sender, e) => { storyboard.Pause(); };
storyboard.Begin();

Change border color of Windows Forms Control on focus

Is there a way to change a border color of some common controls in Windows Forms (TextBox, ComboBox, MaskedTextBox, ...) when they are in focus? I would like to achieve that in my dialog, so when control is in focus it's border becomes blue?
I suggest to draw a rectangle around the active control as the following:
I need a method to get all the controls which in the form, even which they're in nested Panel or GroupBoxe.
The method:
// Get all controls that exist in the form.
public static List<Control> GetAllControls(IList controls)
{
List<Control> controlsCollectorList = new List<Control>();
foreach (Control control in controls)
{
controlsCollectorList.Add(control);
List<Control> SubControls = GetAllControls(control.Controls);
controlsCollectorList.AddRange(SubControls);
}
return controlsCollectorList;
}
Then.. Drawing functionality..
The code:
public Form1()
{
InitializeComponent();
// The parents that'll draw the borders for their children
HashSet<Control> parents = new HashSet<Control>();
// The controls' types that you want to apply the new border on them
var controlsThatHaveBorder = new Type[] { typeof(TextBox), typeof(ComboBox) };
foreach (Control item in GetAllControls(Controls))
{
// except the control if it's not in controlsThatHaveBorder
if (!controlsThatHaveBorder.Contains(item.GetType())) continue;
// Redraw the parent when it get or lose the focus
item.GotFocus += (s, e) => ((Control)s).Parent.Invalidate();
item.LostFocus += (s, e) => ((Control)s).Parent.Invalidate();
parents.Add(item.Parent);
}
foreach (var parent in parents)
{
parent.Paint += (sender, e) =>
{
// Don't draw anything if this is not the parent of the active control
if (ActiveControl.Parent != sender) return;
// Create the border's bounds
var bounds = ActiveControl.Bounds;
var activeCountrolBounds = new Rectangle(bounds.X - 1, bounds.Y - 1, bounds.Width + 1, bounds.Height + 1);
// Draw the border...
((Control)sender).CreateGraphics().DrawRectangle(Pens.Blue, activeCountrolBounds);
};
}
}
Good luck!

How do I create a Treeview with a Context Menu in Silverlight 4?

Silverlight 4 now include the option for creating a context menu upon right clicking. Can anyone provide me with an example of a treeview with a right click context menu for the treeview?
Ultimately I want a the menu to show different options depending upon the node depth selected - bonus points if the example includes this!
You can use this open source menu for this:
http://sl4popupmenu.codeplex.com
The control supports right click on TreeViews out of the box. The code has been adapted from the sample code on the homepage to use a TreeView instead of a DataGrid:
private void GenerateMenu()
{
var data = new ObservableCollection<string>("Item 1,Item 2,Item 3,Item 4,Item 6,Item 7,Item 8".Split(','));
TreeView treeView1 = new TreeView() { Margin = new Thickness(50), ItemsSource = data };
this.LayoutRoot.Children.Add(dataGrid1);
// Create the submenu
var pmTimeSub = new PopupMenu();
pmTimeSub.AddItem("Time Now", null);
// Create the main menu
var pm = new PopupMenu();
pm.AddItem("Delete row", delegate { data.RemoveAt(dataGrid1.SelectedIndex); });
pm.AddSeparator();
pm.AddSubMenu(pmTimeSub, "Get Time ", "images/arrow.png", null, null, false, null);
// Attach the submenu pmTimeSub
pm.AddSeparator();
pm.AddItem("Demo2", delegate { this.Content = new Demo2(); });
// Set dataGrid1 as the trigger element
pm.AddTrigger(TriggerTypes.RightClick, treeView1);
// Showing main menu
pm.Showing += (sender, e) =>
{
pm.PopupMenuItem(0).Header = "Delete " + treeView1.SelectedItem;
TreeViewItem tvi = pm.GetClickedElement<TreeViewItem>();
// Add code to calculate the node depth here using the GetParentTreeViewItem method
// Add code to modify the menu items according to the node depth value.
pm.PopupMenuItem(0).IsVisible =
pm.PopupMenuItem(1).IsVisible = tvi != null;
};
// Showing submenu
pmTimeSub.Showing += delegate
{
pmTimeSub.PopupMenuItem(0).Header = DateTime.Now.ToLongTimeString();
};
}
Note that the code does not allow you to show different menus upon the node depth yet. To do this you can use the following method to get the parent of the TreeViewItem that was clicked:
private static TreeViewItem GetParentTreeViewItem(DependencyObject item)
{
if (item != null)
{
DependencyObject parent = VisualTreeHelper.GetParent(item);
TreeViewItem parentTreeViewItem = parent as TreeViewItem;
return parentTreeViewItem ?? GetParentTreeViewItem(parent);
}
return null;
}
From there you can determine depth of the node by calling the GetParentTreeViewItem function in a loop until the parent is null. You would place this code in the event where the menu is being shown and then add the necessary code in there to show the appropriate menu.
Hope this helps.
So, I tried the above code, downloaded and attempted to include within my Existing Silverlight Application. I was able to find an easier solution. This will add a Context Menu allowing Right-Clicks on the Branches (Headers, or Parent Nodes).
private ContextMenu menu;
foreach(var model in models)
{
// Populate the Tree View Control
var cb = new CheckBox {Content = model.Value};
cb.Click += new RoutedEventHandler(cb_Click);
var header = new TreeViewItem {Header = cb};
// Menu for Header
menu = new ContextMenu();
MenuItem setAsRows = new MenuItem();
setAsRows.Header = "Set as Rows";
setAsRows.Click += new RoutedEventHandler(setAsRows_Click);
menu.Items.Add(setAsRows);
MenuItem addToRows = new MenuItem();
addToRows.Header = "Add to Rows";
addToRows.Click += new RoutedEventHandler(addToRows_Click);
menu.Items.Add(addToRows);
MenuItem setAsCols = new MenuItem();
setAsCols.Header = "Set as Columns";
menu.Items.Add(setAsCols);
MenuItem addToCols = new MenuItem();
addToCols.Header = "Add to Columns";
menu.Items.Add(addToCols);
header.ContextMenu = menu;
treeView1.Items.Add(header);
var thisItem = treeView1.Items;
// Model Contexts
var contexts = myFramework.GetConceptsOfModel(model.Key);
// Add Leafs To Branch
foreach(var context in contexts)
{
cb = new CheckBox {Content = context.Value.ToString()};
header.Items.Add(cb);
}
}

Resources