PivotItem Loaded event fired twice - silverlight

Windows Phone 8, Silverlight. I have a PivotItem that is declared in my page XAML under the ResourceDictionary of the page, because I don't want it to appear initially and there's no dynamic visibility for PivotItems. When the time comes, I take the object, remove it from resources and add it to a Pivot. It works, but the Load event is, for some reason, fired twice - once on page loading and once when I insert it into the Pivot.
I'd rather have my OnLoaded processing only once.
Is that by design? Is there a way around? Is there a similar event that's fired once upon object initialization (except for the constructor)?
I can work around that by introducing an init-once boolean flag, but still.

You can try OnNavigatedTo. A loaded event can fire on all most any item in the visual tree. If you're looking to collapse items on a pivotItem but no the pivotItem itself, then hook into the parent Grid container.
Ultimately, the Pivot control's children can be removed
myPivotControl.Items.Remove(item);
and you can add an item back in the same manner
myPivotControl.Items.Add(item)
However, I suspect you'll have better results using a different event. The parent pivot has event for adding and removing items. This link will take you to the documentation for the Pivot class. In addition, this link will take you to the PivotItem class.

You can make the PivotItem collapsed in the beginning and then make it visible when you need it.

Related

XAML/WPF: Tabbing to textboxes that are inside a tab

I have a WPF/XAML form that has controls on the page and also controls inside a tab control.
I was hoping that by setting the tabindex values appropriately, the user could just tab from the controls outside of the tab control to the controls inside the first tab item, but it seems that the items inside tab control are skipped when tabbing around the form.
Is there a way to have the tabbing go into the tabitem/tab control?
WPF provides a number of ways to affect the tab order in an application. Probably the most important is also strangely the least known. I'm talking about the KeyboardNavigation class and in particular, the KeyboardNavigation.TabNavigation Attached Property. From the linked page on MSDN, this property Gets or sets the logical tab navigation behavior for the children of the element that this property is set on.
There are several possible values in the KeyboardNavigationMode Enumeration used that affect the tabbing order in different ways. Take a look at the last linked page to see which one suits your situation best, but as an example, the Local value has the effect that Tab Indexes are considered on local subtree only inside this container and ... [Navigation leaves the containing element when an edge is reached].
<Grid KeyboardNavigation.TabNavigation="Local">
...
</Grid>
This is a problem I've often faced and it's a tricky one. From my understanding, the reason that it doesn't work as you'd expect is because tab order (even specified via TabIndex) is contextual. TabIndex of higher level items will be prioritized over inner elements. So if you have two TabItems inside of a TabControl, and each one has UIElements inside of them, even if the TabIndex is specified, tabbing will first traverse the TabItems before it moves down to the contents of those controls. I "think", IIRC" this has to do with how the page is composed, but don't quote me on that. MS has weird reasons for some of these subtle nuances.
Onto the solution. What I've done in the past (so long as you're NOT working on WinRT, which makes this problem even worse) you can use UIElement.Focus. I store a list of UIElements in the order I wish them to be when tabbed in the code. Then, by binding the KeyDown event to a common handler for all of these controls, I do something like this:
int currentIndex = TabbableControls.IndexOf(sender);
UIElement next = TabbableControls[(currentIndex + 1) % TabbableControls.Length];
next.Focus();
Hope this helps!

How do I get a UserControl or View to refresh, redraw, repaint, etc.?

I have a situation whereby codebehind in a UserControl populates a Grid object with child Grids containing 1 ColumnDefinition and N Row Definitions. Each row definition contains various user controls.
When the code is done creating the control layout, something is being left over in that controls that have been removed are still appearing on top of the controls that should be there.
I think all I need to do is somehow force a repaint of the screen but how is that done?
I've tried UpdateLayout, InvalidateArrange, InvalidateMeasure, etc etc, nothing will force the layout to refresh.
You don't need any call anything to trigger a re-draw, only to trigger re-layouting and that usually only if you write your own panels.
If you see something, it's in the visual tree.

WPF Performance Degradation During UI Render

I have the following components in a WPF application:
(1) Window
(2) ContentPresenter in the Window that is bound to a property in the underlying ViewModel. This Property references another ViewModel.
(3) A DataTemplate for the ViewModel that will be bound to the ContentPresenter referenced above. This data template instantiates a third-party grid that displays some data.
Whenever the ContentPresenter renders the data from the DataTemplate, it takes approximately three to four seconds for the UI to render. This causes the UI to hang for the duration of the time that it takes to render the content. Since I have little to no control over how the third-party control renders itself - my question involves whether or not it is possible to render content in a way that the UI will not hang.
Please advise.
Thanks.
Chris
How many rows is the grid displaying? And how many of those rows are visible on screen?
I'm asking because it's possible that you've got a UI layout that defeats virtualization. Usually, controls that show a scrollable list of data will perform virtualization. (The built-in ListBox does this, and any 3rd party grid of tolerable quality should do the same.) This is critical for performance, because it means your UI only needs to instantiate those items that are actually visible, rather than everything in your list.
But it's relatively easy to defeat this virtualization by accident. One way is to wrap the list or grid control in a ScrollViewer. You need virtualizing controls to be able to manage their own scrolling for virtualization to work, so the scrolling needs to happen on the inside. Wrapping a control in a ScrollViewer prevents it from doing its own scrolling. Another way it can go wrong is if you plug in a different ItemsPanel. A third possibility is that your list/grid control actually needs to be told to use virtualization.
But if you're using a control that simply takes a long time to render just the stuff you need to show on screen, then there's not much you can do - you'd need to contact the control vendor, or consider using a different vendor...

WPF - Need an event for when VirtualizingStackPanel creates Items for ListView

Is there any way to tell when the containers are finished being made for a ListView?
A detailed explanation of what I've done so far
I have a ListView control that has a DataTemplate in one of its columns that contains a CheckBox Control.. I've figured out how to access the CheckBox dynamically using the object that the ListView is bound to.
ListViewItem lItem = (ListViewItem)ListView.ItemContainerGenerator.ContainerFromItem(trackToHandle);
CheckBox checkBoxToHandle = FindChild<CheckBox>(lItem, "CheckBox");
The problem is that the CheckBoxes "reset" (become unchecked) whenever I scroll too far or whenever I sort the columns.
I figured out this was because the VirtualizingStackPanel was only spitting out containers for those ListViewItems that were visible (or almost visible)..
And because the CheckBox is inside a DataTemplate that is defined in the XAML it gets thrown away everytime it goes out of view or when the list is sorted.
I got around this by creating a separate list of CheckBoxes and using the actual CheckBoxes "click" event to change the state of the corresponding CheckBox in my list.. then made a little method to go change the state of all the visible CheckBoxes whenever the user scrolls... as a result it appears like it should have in the first place.
Except when I sort the columns.
I tried making it re-do the CheckBoxes (like before) right after it'd sorted a column but it didn't work.
My best guess is that it doesn't immediately make the containers after I sort..
Is there any way to tell when the containers are finished being made for a ListView?
If you bind your checkboxes IsChecked property to a boolean property on your data context, then you will not have this issue.
The whole purpose of the VirtualizingStackPanel is reduce memory usage by not creating ListItem's unless needed.
In effect, you need to move the data side of the checkbox away from the control.

WPF DataGrid ContextMenu(s)

How can I define different ContextMenus for each column in the DataGrid (Microsoft's grid)? I found out that the grid provides a ContextMenu attribute, but i want different context menu items for the columns, not the same ContextMenu for the whole grid.
Edit: Thanks for your answer! I tried to listen to the ContextMenuOpeningEvent as you suggested which was a first success: the ContextMenu can be modified in the EventHandler. But it raises another (hopefully small) problem - I now have to identify the column the mouse cursor was over when the ContextMenuOpeningEvent was triggered. I'm going to research how to do (or work around) that later.
I haven't played with it at all, so this might be wrong, but you may be able to override the ContextMenuOpening event and create the appropriate menu on the fly.
add menu item to default context menu might give you a starting point.
Good luck.

Resources