I have a binding for ListViewItem, which is under gridview/listview/scrollviewer.
<Setter Property="IsSelected" Value="{Binding IsSelected}"/>
There's one problem occurred to me:
After I press "CTRL+A" in a ListView/GridView, all items that are currently in the ScrollViewer area will have "IsSelected" set to true.
For all other items in the list, but NOT in the current viewable area of the scroll viewer, the "IsSelected" will NOT be set to "true" unless I scroll them into viewable area manually.
I want to ask is this by design? If not, what I may go wrong?
Thank you.
You are probably using virtualization. So only the "containers" (i.e. ListViewItem) needed to fill the view will be created. You can disable virtualization by setting VirtualizingStackPanel.IsVirtualizing to false on your ListView. This does have a performance hit if you have a lot of data though.
Related
I've got a (hopefully) easy one for you today.
I'm looking to remove the dashed border of a WPF element when it's been selected via keyboard navigation, simply because said marquee is ugly and inconsistent with other styling. I'm only looking to do this on the items of a particular ListBox. I'm hoping there is some SystemColors key I can set, or some other Style property.
Thanks,
-Logix
I found the answer after plenty more searching. Apparently 'dotted line' was the search term I needed, not 'marquee'.
Anyway, here's the solution (from this answer):
In the ListBox style, set:
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
I've been working to improve scrolling performance for an ItemsControl. Initially each item is a simple row of information and when an item is clicked, a detail UserControl is expanded below the item. I'm trying to eliminate the processing being done on the detail UserControl during scrolling. I eventually achieved this with a CustomControl, but I feel like I must be missing a simpler way to do it using the existing framework controls.
Initially, this detail view was a UserControl with Visibility.Collapsed. I should note that Virtualizing and Recycling are enabled for this ItemsControl. Therefore, scrolling performance was poor since each detail view was being bound to the data as the item scrolled into view, even though the detail was not visible.
I then tried using a ContentPresenter where the Content was bound to a DetailViewModel property and the ContentTemplate was set to a keyed DataTemplate. That DetailViewModel property was initialized to Nothing and then set to the appropriate ViewModel object when the item was clicked. This improved scrolling performance because there was no data binding, but I found that the detail UserControl was still getting constructed for each item, and I presume there was some rendering going on as well.
I eventually got the desired behavior with a custom ContentControl that provides dependency properties for GatedContentTemplate and IsGateOpen. When IsGateOpen goes True, the GatedContentTemplate is passed to the ContentTemplate property and the Content is set to the DataContext of the control, which causes the content to then get constructed, rendered, and bound.
<my:GatedContentControl IsGateOpen="{Binding IsDetailVisible}">
<my:GatedContentControl.GatedContentTemplate>
<DataTemplate>
<my:DetailUserControl/>
</DataTemplate>
</my:GatedContentControl.GatedContentTemplate>
</my:GatedContentControl>
I can live with this solution, but it's a little janky, and I wonder if I'm missing some way that WPF intends for this to be done.
Looks like I wasn't missing anything and this is a need that Microsoft is addressing in .net 4.6.
The Content Deferral feature is discussed in this video, starting at 26:30.
http://channel9.msdn.com/Events/dotnetConf/2015/WPF-in-46-and-beyond
Thanks for the comment HighCore.
I'm wanting to have a tooltip for disabled TabItems in a TabControl. The standard way of putting tooltips onto disabled controls in Silverlight is by wrapping the control in a dummy element that has the tooltip, but I can't get at the TabItem like that. The TabItems' host control is a TabPanel, which doesn't seem to expose any useful properties.
Any ideas?
I had the same problem with putting a Toolip on a disabled menu item, i solved it by changing the VisualState of my menu item to Disabled and then disabling the MouseButton events.
VisualStateManager.GoToState(tabitem, "Disabled", true);
You'll have to be careful with other events though, because the VisualState will change according to different events. It's not a perfect solution, but it will work for certain scenarios.
Hope this helps
My current workaround for my own problem:
I've got a TabControl Behavior that finds the "TabPanelTop" template part (or left, right, or bottom depending on TabStripPlacement), along with the "TemplateTop". I add a Canvas into the TemplateTop (which is a Grid), and fill it with Transparent Rectangles whose positions (using TransformToVisual) and sizes are calculated (and updated) to be the same as the TabItems, which are the children of the TabPanelTop.
The visibility of the Rectangles is bound to the inverse of TabItem IsEnabled, and the ToolTipService.ToolTip is bound to the ToolTipService.ToolTip on the TabItem.
It's a bit scary but it works and is easy to use.
I'm binding a list of object to an ItemsControl which contain a TextBox control.
I want to be able to change the textbox background color based on the background color property of the bind object.
It works perfectly with the INotifyPropertyChanged interface but when I need to update let say 1000 objects it takes a huge amount of time I guess because it needs to update the controls one by one.
Does someone has a tip for me to lets say, update all my objects background color and than update the binding in one shot instead of object by object?
Thanks,
Mat
If you use virtualization, it'll only need to update the items that are visible - normally items controls will only track property changes on the items that are currently visible. However, if you're using the base ItemsControl, virtualization will be off by default. To turn it on, you need to provide a custom template that includes a ScrollViewer with CanContentScroll set to True, and you also need to use a VirtualizingStackPanel, either in the control template, or via the ItemsPanel - this shows the former approach:
<ItemsControl ItemsSource="...whatever...">
<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<ScrollViewer CanContentScroll="True">
<VirtualizingStackPanel IsItemsHost="True" />
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
</ItemsControl>
Virtualization improves performance with large numbers of list items in various ways. It should help your scenario, but it may also improve other aspects of the performance. It's not without its problems, but I'd definitely try it here first before attempting other solutions.
I finally found why it was taking me so long to update my UI. Byt the way, What I'm trying to achieve is a kind of spreadsheet grid. My cell container was a border with the borders visible. I was updating the Border control Background color based on cell selection. Disabling the borders of the Border control resolved my issue right away. The UI update time went from 4-5 seconds to instantaneous.
Thank you guys for your answer, I will still try to implement your suggestion to improve even more my project.
Thanks
Mat
I am using a TabControl to programmatically show or hide groups of form controls. I have implemented the technique described here and it approximately works as expected, except that there is a band approximately 1 or 2 pixels high in the location where the tab headers are normally displayed.
I have verified this by using Snoop to navigate the visual tree and observe the movement of the highlight rectangle as each element is selected. The size of the rectangle for the tab content element is fractionally smaller than that of the containing TabControl, which accounts for the extra pixels I am seeing. None of the elements that might affect this have margin, border or padding.
To achieve proper alignment with other controls, I need to eliminate this extra space, but I am not sure how. However, perhaps the question I should be asking is "is there a better way to selectively show / hide groups of controls?".
Thanks for your ideas,
Tim
I suppose the thin line is caused by the TabPanel which is still there even though all TabItems are collapsed.
However, you could change the TabControl's ControlTemplate and bind the TabPanel's Visibility to the number of tabs, like this:
<TabPanel ... Visibility="{Binding Items.Count, RelativeSource={RelativeSource FindAncestor, Type={x:Type TabControl}}, Converter={StaticResource ZeroToCollapsedConverter}}" ... />
Of course, you will have to implement a converter which converts 0 to Visibility.Collapsed and all other values to Visibility.Visible.
BTW: You can get the default ControlTemplate for the TabControl here.