WPF Combobox - DataBind Empty Space Issue - c#

I have a simple combobox bound to a List where A has a property Key and a property Value.
The combobox binds fine and works except for one flaw. It has a large empty space at the bottom where there are no items (i.e they don't get highlighted on hover or any such thing, there are no extra items, it is just that there is an empty space). How can I get rid of it?
http://i.stack.imgur.com/2yN9r.jpg

This is most-probably because of the template of the ComboBox under your current theme. Try changing Windows theme to Aero or Luna (seems like now you have it set to Classic).
If that's the issue, then there's a way to "fix" it by using a custom template, but then you break consistency from user's point of view. You'd need to take it into consideration.

you need to change the Template of combobox and reset the popup height acordingly. check below.
http://msdn.microsoft.com/en-in/library/ms752094%28v=vs.85%29.aspx
Search for popup under the tempalte and add the minheight=0 into it.

In my ComboBox ItemsSource="{Binding MyItems..., if MyItems is a List, it will leave extra space. if MyItems is an ObservableCollection, the extra space goes away. This may due to a Microsoft bug that ItemsSource was not properly notify by MyItems change when it is a List object.

Related

Why are some properties unaccessable

I was trying to get the text that I wrote in a DataGrid cell after editing it, so I put a breakpoint in the function CellEditEnding and looked at the EventArgs and noticed that it contains the property "Text", so I wouldn't have to do the usual XAML binding hacks to get it.
However, I quickly noticed that it will not let me access it.
After taking a look at the FrameworkElement class, I can confirm that there is no Text property, so what is going on, why can't I acces the property?
why can't I acces the property?
Because a FrameworkElement indeed has no Text property.
TextBox, which derives from FrameworkElement, has a Text property though so you could cast the EditingElement to a TextBox and then access the property:
string text = (e.EditingElement as TextBox)?.Text;
Visual Studio displays the properties of the actual object in memory.
It's a bad idea to use the UI as a data store and try and directly work with it.
You should bind an observablecollection of t to the itemssource of your datagrid and work with each instance of t.
That will be far easier to work with.
As to why are some properties inaccessible?
It's because those properties aren't where you think they are. The DatagridCell has a series of things nested within it.
DataGridCell > Border > ContentPresenter > TextBlock
Download snoop https://github.com/snoopwpf/snoopwpf or install using chocolatey / your preferred method.
Run snoop.
Run your app.
Drag the right gunsight thing over you window.
A window should open up with two panels. Controls and properties.
Mouse over a datagrid cell.
press shift+ctrl and you should see the element under the mouse selected in the ui tree.
A datagrid is pretty complicated and there are multiple things in each row.
See that textblock there?
That's the thing has a text property.
Or at least that's the thing when you're not in edit mode.
Switch to edit mode and I have a TextBoxView.
So one complication is, which are you working with at a given time?

Deal with wpf ComboBox ItemsSource changing upon selection

I have a wpf user interface in which I use ComboBox to set a property to a value. The ItemsSource of the ComboBox has a Binding to a list of allowed values. I have made it so that this list is the list of allowed values but with the value currently selected removed from it. This way the list only contains values that one can actually change to. When the list is empty, I have a trigger that makes the combobox inactive.
This is all working well in terms of expected behaviour. However visually I have multiple red borders showing validation errors due to the fact the selectedvalue is no longer in the itemssource list upon update. There is no red border when I do not remove the currently SelectedValue from ItemsSource upon update.
Is there a way to get around this, maybe another Control I could use, or maybe somehow validate the SelectedValue from another list (that would contain the current value) compared to the one in ItemsSource ?
You can't actually select a value that is not in the ItemsSource. What you can do is to remove the red border that shows up when there is a validation error by setting the Validation.ErrorTemplate attached property to an empty ControlTemplate:
<ComboBox ...>
<Validation.ErrorTemplate>
<ControlTemplate/>
</Validation.ErrorTemplate>
</ComboBox>

Update DataTemplate for a specific item on a listbox on Windows Phone 8 C#

I'm not being able to update a single item's DataTemplate on a list during runtime. In detail, here is what I'm trying to accomplish.
I have a Listbox where the items can have different states (Collapsed, expanded, disabled, etc), each with a different layout. I'm using a TemplateSelector to choose the correct DataTemplate according to a property on my class and that's working all great when I first create the list, the items are shown properly. However, when I change the property that sets the DataTemplate in runtime, the NotifyPropertyChanged is called and the information of the item is updated on the list, but not the DataTemplate. For example: I have a collapsed item with a label X that i want to expand. I click on the item and the label changes to Y but the DataTemplate doesn't update.
Any idea on how I can do this? Can't the DataTemplate be updated during runtime unless it is for the whole list?
I'll appreciate any help.
Make UserControl and use it inside your data template. Now, to change the state you can call methods on this UserControl and it will update. You can use animations via storyboard too.

Not showing items with Visibility=Collapsed in Windows 8.1 GridView

I have a Windows 8.1 application with a GridView bound to a custom (sortable, deduplicated) observable collection. In this collection, I do some heavy filtering and setting an IsHidden flag for every item.
In the data template for the item, there is a condition making the item collapsed if IsHidden flag is set to true.
<Grid Width="160" Height="280" Visibility="{Binding IsHidden, Converter={StaticResource InvertedBooleanToVisibilityConverter}}">
This approach works in Windows Phone 8.1 XAML, making the items disappear from the ListView but it does not work in Windows 8.1 GridView. The problem with Windows 8.1 is that when I set an item in the collection to hidden, id disappears from the GridView but leaves an empty place, so there is a gap in the GridView.
Any ideas on how to solve it? Maybe same XAML style editing?
Here is a minimal solution to reproduce the problem: https://dl.dropboxusercontent.com/u/73642/gv.zip
I tried binding width and height of the items to the hidden flag and setting it to 0 when the item is hidden, but it did not help, still a gap in the GridView.
Update: One workaround would be filtering the actual bound collection, but this is not possible, because of some business requirements.
The problem is in the GridView's ItemsPanel.
Both ItemsWrapGrid and WrapGrid are uniform grids. All their child elements will be sharing the same height and width. That's why even if you collapse the ItemTemplate, the space is still reserved.
What you really need here is a WrapPanel. WINRT doesn't have a built-in WrapPanel but Jerry Nixon has built one and you can grab it from here.
After you updated your GridViews ItemsPanel, you still have one more thing to do. You need to also get the GridViewItem that hosts your Itemtemplate and set its Visibility to Collapsed.
private async void Button_Click(object sender, RoutedEventArgs e)
{
ds[5].IsHidden = true;
await Task.Delay(1000);
var gridViewItem =(GridViewItem)this.gv.ContainerFromIndex(5);
gridViewItem.Visibility = Visibility.Collapsed;
}
I put a little delay above to make the collapsing more obvious.
I tried your sample solution and changed it to a ListView instead. It exhibits the same behavior when the grid itself is hidden. I don't have XAML Spy to verify, but it appears that any List based control will allocate a rendered item for each item in the list.
I changed your click handlder to instead ds.RemoveAt(5); instead of hiding the item, and the element is removed from view with a nice animation. This appears to be as expected, and an interesting find.
It takes me a lot of time to understand the problem, and the solution right in front of my eyes. You trying to hide the item itself but the container still there, When you add an item to an GridView, the item is wrapped in an item container. from msdn :
" When you add an item to an ItemsControl, the item is wrapped in an
item container. For example, an item added to a ListView is wrapped in
a ListViewItem. Without UI virtualization, the entire data set is kept
in memory and an item container is also created for each item in the
data set. A ListView that's bound to a collection of 1000 items will
also create 1000 ListViewItem containers that are stored in memory."
You need to disable the container and create two DataTemplate and using DataTemplateSelector you can choose which DataTemplate for disable and active items. Check this useful article .

LongListSelector automatically at bottom

So I'm getting a weird behavior with the native LongListSelector from WP8.
It's ItemSource is bound to an
ObservableCollection<Group<Something>>
Everything is displayed correctly, but when the list appears on screen, I'm at the bottom of the list instead of it's top.
The only thing I do is to fill the ObservableCollection via it's Add() Method.
Is this a known behavior or is there a workaround ?
It is a normal behaviour as you are adding items one-by-one. for required behaviour kindly feed the list and then set it to observable collection

Categories