| Derek's profileDerekDevDudeBlogListsSkyDrive | Help |
|
Items of interest, that I'll one-day get around to looking at.
|
DerekDevDudelives here July 03 Hide/Show GridView Column using Attached BehaviourThe default GridView column behaviour doesn’t include direct support for hiding a column. For a better user experience I want
To implement these capabilities, I’ve used an Attached Behaviour: Column. Point 1: This was the simplest to resolve. The suggested approach for hiding a column is to set its width to zero (MSDN Forum), but this doesn’t stop the user from re-showing the column by simple dragging it open again, and I didn’t want code in my view (hence the use of an attached behaviour). A simple solution for this is to set the column header IsHitTestVisible to false for a hidden column. Point 2: This is a straight forward AB added to the GridViewColumnHeader. The property just listens for mouse double click events, and set the corresponding column’s width to auto. Point 3: This was a more difficult problem.The ViewModel binds to the style for a WPF UIElement, but the column width is defined by the GridViewColumn, not the GridViewColumnHeader UIElement. My first thought was to just style a GridViewColum to bind it to my ViewModel, but since a GridViewColum is not a UIElement, styles don’t apply. My final approach was to Attache a Property “IsHidden” to the GridViewHeader this makes it easy to bind to. It also provides a convenient place for disabling header interaction (see point 1) when the column is hidden. Point 4: My first approach for an AutoHide behaviour was to attach a property to the GridViewColumn. This had 2 down sides
So alternately I opted to follow the IsHidden approach, and set the property on the column header. I found a few ‘surprises’ implementing AutoHideWidth:
To use the behaviour, you just set it in the view XAML: <!-- Style column header with the behaviour --> To get the binding between view model IsShowing property and the grid column, I just set the column header to a view model object, then bind it in the header’s style.
<!--Set the Column header to a view model object. --> I’ve included a sample showing a GridView with this behaviour attached here. June 29 An approach for Sorting a ListView in WPF.In WPF sorting on a ListView is managed via the collections corresponding CollectionViewSource. In XAML, a designer can define the sorting via setting the CollectionViewSource. There are also MSDN samples to show how to sort based on user clicking the column header. In my particular case I needed more complex sorting behaviour.
In this demo I’ve tried to apply a MVVM style design to sorting items in a list view. Model: View Model:
Each sort-able column is represented as a Term.
I’ve used the DelegateCommand<T> and the Click attached behaviour from CAL-Feb 2009 release (http://compositewpf.codeplex.com/). View: To show a sort-direction indicator, I need to track the sort column’s current sort direction (descending / ascending / null). Ideally a column header would be a tri-state toggle button, so I could bind a sort-direction to the IsChecked property of the button. But the column header is a press-button, not a tri-state button. Initially I attempted to style the column header template to use a toggle button, but this caused other problems, such as losing the drag-reorder ability on a column. So instead I’ve included a bound toggle button in the header’s data template, and bound this to the corresponding Term’s sort direction. I then use a command behaviour on the column header button to toggle the sort. Finally, a little styling on the toggle button so it looks like an up/down arrow (Media/UpDownToggle.xaml). Note: A GridViewColum is not a framework element, so I couldn’t use a style to apply the HeaderTemplate. Also the HeaderContainer doesn’t get the Header object as it’s data context, so I needed to explicitly set the ToggleSort command for each column. Code: the demo source is here (http://cid-e0c1236f30f0febc.skydrive.live.com/self.aspx/Public/ListViewSorting.zip). May 27 A WPF ComboBox styled as a DropListOut of the box a WPF ComboBox, in read mode (IsEditable == false) disables interaction with the current selected item, but allows interaction with list items. This behaviour causes problems if the DataTemplate for your items includes interaction elements, such as Buttons, or as in my case Hyperlinks. Ideally this behaviour should be reversed; the list items should be selectable (but not interactive) whilst the selected item should be interactive. To solve this, firstly I created a non-clickable style for a ComboBoxItem (NoClickComboBoxItem). The trick for this is to disable hit testing on the data template using the IsHitTestVisible property: <Style x:Key="NoClickComboBoxItem" TargetType="{x:Type ComboBoxItem}"> The next part is to make the selected item interactive. The default ComboBox’s control template sets the IsHitTestVisible to false for the displayed selected item, so we need to
replace the ComboBox’s Template with our own.
<ControlTemplate x:Key="DropListNormal" TargetType="{x:Type ComboBox}"> To keep things clean, I’ve put both these ControlTemplates in a Style
<Style x:Key="DropListCombo" TargetType="{x:Type ComboBox}"> Applying this to a ComboBox is now just setting the Style
<ComboBox You can find a sample of this style here. Note: I’ve based the template on the default ComboBox template, so I also need to include style’s for the button. May 26 Binding a ComboBox with MVVMI ran into a problem using MVVM and a ComboBox. I was using a simple approach with each list item exposing an IsSelected property, and WPF style to bind the property to the view. Strangely the initial display of the ComboBox wasn’t displaying the current selected item, till the user first dropped-down the combo. Eventually I found a link describing my problem here on MSDN; basically the drop-down ComboBoxItem’s aren’t created until needed, and as a result, the IsSelected isn’t initially applied. The problem is easy to reproduce; a simple application with a list of items (Book 1, Book 2, Book3, Book 4), with the 3rd item selected, then bound to a combo box something like:
/// <summary>/// A simple interface to identify a viewmodel item as selectable./// </summary>public interface ISelectable { bool IsSelected{get;set;}} The PopUpCollection itself inherits from ObservableCollection, adding a SelectedValue property. It also registers to with each contained item’s INotifyPropertyChanged event (via WeakEventListener) to track changes to IsSelected. public class PopUpCollection<T> : ObservableCollection<T>, IWeakEventListener Now in the view I simply bind the ComboBox SelectedValue to the PopUpCollection’s Selected value: <StackPanel Orientation="Horizontal"> I’ve put this in a sample app here. April 29 Showing Design Data with WPFwhen developing in WPF, using MVVM it is very useful to provide some design-time data to help check bindings, and to give some visual feed-back. Below is my (current) approach for providing design-time data:
Advantages:
Disadvantage:
|
Active presence in the virtual world
|
|||||||||||||
|
|