In my WPF application I have created and added a new Grid, I already know how to remove all Children from it:
private void ClrScr()
{
for (int i = GridName.Children.Count - 1; i >= 0; i--)
{
GridName.Children.RemoveAt(i);
}
}
But I have no idea how to kill the grid itself, my tries:
GridName.Exit/Disable/Something; /// <--- no Idea what am I doing...
this.Controls["GridName"].DIEEEE;
Sadly I have failed... I am very new to WPF, I've mostly played with WinForms... Help?
You can remove the grid using it's parent.
e.g: If you have three grids named grid1, grid2 and grid3 in a dock panel control named main, you can remove these grids like this:
main.Children.Remove(this.grid1);
main.Children.Remove(this.grid2);
main.Children.Remove(this.grid3);
All the controls in WPF has parent except form. If the Grid you are going to delete is the first then you can do this:
var parent = myGrid.Parent;
Window window = parent as Window;
if(window!=null)
window.Content = null;
Sometimes Grid can be child of a control which doesn't have Content property. If it doesn't have Content then it must have Children or Items.
Related
I have a window form that has a control treeViewMain and in the code I have a list of treeViews that has variable number of treeViews. I want the treeViewMain to show anyone of the treeView from the list.
treeViewMain=treeViews[0];
but the form is not showing the tree. Also I have thoroughly checked the treeViews in the list, they are populating correctly.
Apparently simple assigning does not work. According to this post it seems that the parent of a TreeViewNode has to be unique and there by the "fruit" can only sit at one tree.
One workaround could be to set the parent property of the TreeView in your list to the treeViewMain:
treeViews[0].Parent = treeViewMain;
this will put the treeview from the list as a child inside treeViewMain. If you want to change that and load the next item from your list you need to make sure that the previously loaded item's parent property is set to null before assigning a new parent like in this example:
private int count = 0;
private void button_ChooseTreeView_Click(object sender, EventArgs e)
{
if (count > 0)
{
treeViews[count -1].Parent = null;
}
treeViews[count].Parent = treeViewMain;
count++;
}
The other possibility would be to clone each node and populate the treeViewMain each time you want to update the list items to the display
I have an instance where the details template has two main stack panels within it.
One is set to collapsed by default. However upon right click and choosing, that stack panel's visibility is to be triggered. This may occur when the row details are expanded already.
However when the row details are expanded and the right click is chosen to view that stack panel, I'm programmatically changing its visibility to Visible but it's not becoming visible.
Is there a secondary call I need to make to update the UI and force the visibility setting to take?
Here's my code:
private void SetWFHistoryVisibility(bool show)
{
var elements = VisualTreeHelper.FindElementsInHostCoordinates(position, this);
var row = (from element in elements
where element is DataGridRow
select element).FirstOrDefault() as DataGridRow;
if (row != null)
{
DataGridDetailsPresenter presenter = VisualHelper.FindVisualChild<DataGridDetailsPresenter>(row);
if (presenter.Children.Count > 0)
{
var grid = (from el in presenter.Children
where el is Grid
select el).FirstOrDefault() as Grid;
if (grid != null)
{
StackPanel wfgc = grid.FindName("wfGridContainer") as StackPanel;
if (show)
wfc.Visibility = System.Windows.Visibility.Visible;
else
wfc.Visibility = System.Windows.Visibility.Collapsed;
}
}
}
}
You may need to call DataGridView.Refresh(), or equivalent depending on your panel/layout. Also it can be a parent control as well needing to update/refresh.
I know that in Silverlight DataGrid does have an AutoRefresh, but it is primarily controlled by an EventTrigger either in a DGV or DataGrid class. As you discovered it isn't perfect.
Perhaps you can trigger one of the following events and allow the Control to work out it's own view update.
https://msdn.microsoft.com/en-us/library/system.windows.controls.datagrid(v=vs.110).aspx
This one solution:
Dispatcher.BeginInvoke(() => {
//set the added control to be visible
});
Was suggested by a user on MSDN for StackPanel refreshing.
Several other suggestions suggest utilizing a combination of:
_.Invalidate()
_.UpdateLayout()
For forcing a refresh.
I'm facing the fact that i cannot understand Well how AdornerLayer is added for UIElements.
I have such a situation:
I have a WPF Form which is built with 3 controls:
A Grid on which are 1 Button and 1 TextBox.
In my System, when I click to open this Form, all 3 elements have AdornerLayer not null .
var controls = _frameworkElementProvider.GetUIElements(Content);
var controlsWithAddorner = new List<FrameworkElement>();
foreach (var control in controls) {
var adornerLayer = AdornerLayer.GetAdornerLayer(control);
if (adornerLayer != null) {
controlsWithAddorner.Add(control);
}
}
The collection controlsWithAddorner contains all my 3 controls.
The method GetUIElements(FrameworkElement parent) returns an IEnumerable<FrameworkElement> in which are all controls within a Panel.
I have such a functionality:
Refresh Form Designer. Which recreates the xaml for that Form.
After that Refresh is done, I check the list of controls for AdornerLayer. For all controls the AdornerLayer is null.
The problem is here, I cannot understand where AdornerLayer (s) are lost?
Should I take care To add them forr each UIElement when I Refresh the Designer of the Form?
Please advice me with some suggestions.
Thank you!
EDIT:
I'll show all the solution if other will encounter such problems :)
The mission is: When there is a SelectedControl in designer, keep it selected even a RefreshDesigner is done.
RefreshDesigner functionality recreates the xaml for the whole form.
// Refresh the Designer
private void RefreshDesigner() {
Content = _xamlProvider.ParseXaml(_xaml.ToString());
//Here was the Problem. All visual child elements of the Content wa not updated after xaml recreation.
//By including that call -> solved the problem
Content.UpdateLayout();
}
Firstly: The xaml of the Form is Updated by using the ParseXaml() method from XamlProvider
// in XamlProvider class
public Panel ParseXaml(string xaml) {
var regex = new Regex("<Grid ");
const int first = 1;
xaml = Regex.Replace(xaml, #"xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml""", string.Empty);
xaml = Regex.Replace(xaml, #"xml:space=""preserve""", string.Empty);
//...
xaml = Regex.Replace(xaml, "<BindingGroup .*/>", string.Empty);
var content = (Panel)XamlReader.Parse(xaml);
return content;
}
Secondly: Content.UpdateLayout();
Ensures that all visual child elements of this element are properly updated for layout.
MSDN Official source
After that, All elements have AdornelLayer not Null and I'm able to set the Adorner Border for preciosly selected control in designer.
After the Form is Refreshed, call Content.UpdateLayout(); to Ensures that all visual child elements of the Content were properly updated for layout. MSDN official
I have a form done in WPF which has a custom control already on it called RateView. This custom control has 4 textboxes (which are all working as they should be). It also contains a button.
I have a second custom control called Extended Margin Info, which also has a XAML Form which will just show output data only.
How can I by clicking the button on the custom control called Rateview bring up the XAML canvas onto my Main window of the extendedmargin info XAML, in the same position everytime? Rateview control exists 5 times on the main window therfore there will be 5 buttons that when clicked, will need to output the popup of ExtendedMargin Info to the main screen in the same position each time with the content of extendedmargin info.
Your button, when clicked, should call a Command which updates a Property of some ViewModel that exposes the ViewModel of the current ExtendedMarginInfo you want to display. Then you can bind this property to the Content Property of a ContentControl in the target view. You can select the View you want the Control to display by using the ContentControl.ContentTemplateSelector property.
I guess you want show one popup and change it's content placing in it different controls.
At 1st create your custom control:
balloon = new LogEntryInfoBalloon();
balloon.SetMainWindow(this);
balloon.DataContext = vm.NotificationViewModel;
Then create Popup control (System.Windows.Controls.Primitives):
localPop = new Popup();
localPop.AllowsTransparency = true;
localPop.Placement = PlacementMode.AbsolutePoint;
localPop.StaysOpen = true;
localPop.PlacementTarget = this;
localPop.Child = balloon;
Placement target points to MainWindow.
Define timer that will close(hide) balloon:
localPopTimer = new Timer(new TimerCallback(CloseLocalPopup));
Close func:
private void CloseLocalPopup(object args)
{
var act = new Action(() =>
{
localPop.IsOpen = false;
});
Dispatcher.BeginInvoke(act, null);
}
Show balloon code looks like this:
private void ShowNotifyBaloon(NotifyBaloonViewModel vm)
{
var act = new Action(() =>
{
localPop.IsOpen = true;
localPopTimer.Change(4000, Timeout.Infinite);
});
Dispatcher.BeginInvoke(act, null);
}
I have written code that will resize a Control and all of its controls, but there's a problem with the PropertyGrid. The user interface is a GroupBox that contains the TabControl tabContAll. In tabContAll is a TabPage that contains a PropertyGrid.
private void ResizeUI ()
{
ui.Location = new Point (this.ClientRectangle.Left, this.ClientRectangle.Top + menubar.Height);
ui.Size = new Size (this.ClientRectangle.Width, this.ClientRectangle.Height - menubar.Height);
ResizeControl (tabContAll, ui);
}
private void ResizeControl (Control control, Control parent)
{
control.Location = new Point (parent.ClientRectangle.Left, parent.ClientRectangle.Top);
control.Size = new Size (parent.ClientRectangle.Width, parent.ClientRectangle.Height);
foreach (Control child in control.Controls) {
ResizeControl (child, control);
}
}
This function is called when the form loads, and this is what it looks like compared to if I commented out the resizing in the loop so the PropertyGrid doesn't get resized:
Furthermore when it is resized, the description doesn't work. It just shows the name of the property.
I strongly recommend you to not write code for controls resizing unless you need a very very custom behaviour.
Set Control.Dock or Control.Anchor properties instead, and leave the rest to them.
For example, your case can be solved easily by setting the Dock property to DockStyle.Fill for both your TabControl and PropertyGrid (and obviously removing the custom resizing methods).
Here's a complete MSDN Walkthrough for WinForms custom controls design:
http://msdn.microsoft.com/en-us/library/6hws6h2t.aspx