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>
Related
I have a DataGrid I bound to an ObservableCollection. The grid is configured in a way that the user can add rows (this is the desired behavior). Elsewhere in my GUI, I bound the same collection to be the ItemsSource of a ComboBox. There, it shows the {NewItemPlaceholder} I don't want.
I found a similar question where it is suggested to set CanUserAddRows to false but then I would need a dedicated button or context menu item to add a new row which I find less intuitive.
So, is there a way to get rid of this placeholder by e.g. some means of filtering the ItemsSource?
Followup 1
I discovered the following strange behavior:
When I directly bind the ItemsSource of the combo box to the observable collection, I get the {NewItemPlaceholder}
When I declare a CollectionViewSource as a Resource of my combo box, set its Source to the observable collection and set in turn my CollectionViewSource as the ItemsSource of the combo box, the {NewItemPlaceholder} disappears. I don't even have to specify a filter.
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.
I am trying to implement a little search module in a WPF application. The results of the search are bound to a ListView and I want to set the focus on the first item of this ListView as soon as it is populated with new results.
The solution of this question - Set Item Focus in ListView WPF - suggests calling ContainerFromIndex(int index) method to get the necessary ListViewItem. Trying this at the very end of my search procedure returns null. So, I deduce that although the source of the ListView has been populated, the view itself isn't updated at this moment.
The next thing I tried is handling a SourceUpdated event of my ListView. It doesn't fire. I added NotifyOnSourceUpdated=True to the binding as was pointed out in the answer of this question - sourceupdated event not firing - but the event still doesn't fire.
I'll just add that the binding itself works. So, what is the right way to set focus on the first item (or on any other item) of a ListView?
EDIT: I'll supply the relevant part of the XAML to make things more clear:
<ListView Name="foundRequestsListView"
IsSynchronizedWithCurrentItem="True"
utils:GridViewSort.AutoSort="True"
ItemsSource="{Binding Path=FoundRequests, NotifyOnSourceUpdated=True}"
SourceUpdated="foundRequestsListView_SourceUpdated" >
<ListView.Resources>...</ListView.Resources>
<ListView.View>
<GridView>...</GridView>
</ListView.View>
</ListView>
FoundRequests property is an ordinary List.
EDIT: Calling UpdateLayout() beforehand solves the problem.
The problem is solved by calling UpdateLayout() method before trying to get a ListViewItem.
One way that you can achieve your requirement is to use the selected item that you say you have to access the associated ListViewItem that you can focus. Try this:
ListViewItem item = YourListView.ItemContainerGenerator.
ContainerFromItem(YourSelectedItem) as ListViewItem;
Once you have the associated ListViewItem, you can focus it simply, like this:
item.Focus();
Bind the SelectedItem to a property in your ViewModel.
SelectedItem="{Binding PropertyNameHere}"
When the selected item is changed on the collection, it will also be updated on the property bound to the selected item.
So at the end of your search procedure, simply set the bound property to the first item in the collection.
if (FoundRequests.Count > 0)
PropertyNameHere = FoundRequests[0];
You do not need to worry about INotifyPropertyChanged for the bound property.
I have combobox that is bound to a collection. Each item in the collection has a subcollection that might or might not contain items. I have a second combobox to which the subcollection is bound. And I only want to display (=Visibility.Visible) the second combobox if the subcollection has items. All that works. BUT: When I start my program, the selectedItem of the main combobox is null (=so far nothing has been selected). This (I guess) causes the converter to not be called (it doesn't, I have set a breakpoint on the converter and the program does not halt when it starts).
So I have the problem that I don't want to display the second combobox when the program starts. Can I force the ValueConverter to be called? I have tried invoking OnPropertyChanged at the end of the constructor, but that doesn't change anything. And when I set the combobox to Visible.Hidden in the constructor of the .xaml.cs, it will not show at all, even after the value converter is called. Any ideas?
Set a FallbackValue for the binding:
<SomeUIElement Visibility="{Binding SomeBinding, Converter={StaticResource SomeConverter}, FallbackValue=Hidden}" />
When there is nothing bound you can set a value that will be used in place of the binding.
The reason changing the value in code-behind to Visibility.Hidden leaves it invisible all the time is because setting the property explicitly removes the binding that you have added in the XAML
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.