I try to modify selected item by code of a RibbonComboBox:
<r:RibbonComboBox x:Name="RibbonComboxBoxEditEnemyProjectiles" Label="Projectile" SmallImageSource="img/history16.png">
<r:RibbonGallery SelectedItem="{Binding Path=iSpriteIdx}" >
<r:RibbonGalleryCategory ItemsSource="{Binding oProjectiles, Source={StaticResource GameInfos}}" />
</r:RibbonGallery>
</r:RibbonComboBox>
I try 2 ways :
RibbonGalleryEditProjectileSprite.SelectedItem = GameData.oSprites[ idx ];
RibbonGalleryEditProjectileSprite.SelectedValue = GameData.oSprites[ idx ];
This ways don't work. What is a correct way to do that ?
Thanks
If you search this website before you post questions, you can find good answers... Take a look at this post and this post.
UPDATE >>>
The How to set SelectedItem on a RibbonComboBox using MVVM? post that I gave you a link for has a complete solution for you. Basically the answer is this:
Whatever object that you set as the RibbonGallery.DataContext should have a collection property to bind to the RibbonGalleryCategory.ItemsSource property and a property of the same type as the collection items to bind to the RibbonGallery SelectedItem property.
Let's say that your selected item property is called SelectedItem. You will then be able to set the SelectedItem property of the object that you set as the RibbonGallery.DataContext to an item from the collection and the binding will change the selected item in the RibbonGallery UI.
Note that if you are using objects as your gallery data types (as opposed to primitives like string, etc.), then this will only work if you set your SelectedItem property to an actual item from the collection and not just one with the same values. This can be easily achieved if your data object has a property with unique values by the following:
DataContextData.SelectedItem = DataContextData.CollectionData.Where(d => d.Id ==
itemToSelect.Id).Single();
If that still hasn't helped, I did a quick search online and found a complete solution that you can download and examine at your leisure in the How do I add Galleries to my Ribbon? post at 'The official blog of the Windows Presentation Foundation Team'. It shows a good example of the method that I just described.
Related
I'm using Realm as my main database and sync engine and my question is that how do I do live queries for search?
for example when I use
var _age= 7;
Instance.All<Dog>().Where(d => d.Age == _age).AsRealmCollection();
and bind my listview to it, I need my view to be updated when I change the _age variable. As another word, I want to have a "Dynamic" query to my database. I want my view to be updated when I want to look for "Dogs" in different ages. But when I run this query again and assign new collection to ViewModel, my view does not update.
What shall I do?
UPDATE:
Here you can get a sample code so you can reproduce this issue:
https://github.com/Mohsens22/RelamTest
Also I must tell you that IRealmCollection<T> implements INotifyPropertyChanged by default so if you add any items to the collection with a "Write transaction" the view will be updated. More info can be found HERE
I have checked your code sample and I found Dogz will be recreate with Instance.All<Dog>().Where(z => z.Age == nxt).AsRealmCollection();. So you need two way bind model.
<ListView x:Name="itemListView" ItemsSource="{x:Bind Dogz,Mode=TwoWay}">
And this is document about bind that you could refer.
I have a collection of items, which I have bound to an ItemsControl:
<ItemsControl ItemsSource="{Binding ProductCategories, Mode=TwoWay}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ToggleButton IsChecked="{Binding IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<TextBlock Text="{Binding CategoryName}"/>
</ToggleButton>
I then have a second items collection which, in my view model, is based on a query, dependant on the above collection.
So, my requirement is to filter a list of products, based on the above category. The problem that I have is that the above binding is to a ProductCategory; so, while the set fires correctly for the 'IsSelected' property on ProductCategory, it doesn't notify that the 'ProductCategories' has changed.
ProductCategories is defined as:
public class ProductCategories : ObservableCollection<ProductCategory>
My first thought was that I could achieve this by using a DataTrigger; however, these don't seem to be available since WinRT. I could also use some kind of message notification for this, but I feel like this is something that should be achievable directly from the XAML binding.
So, my question is, is it possible to raise a notify that the parent class has changed, when the child class is changed.
DataTriggers are available in UWP using this nuget package https://www.nuget.org/packages/Microsoft.Xaml.Behaviors.Uwp.Managed
Here the link to the wiki https://github.com/Microsoft/XamlBehaviors/wiki/DataTriggerBehavior
Using this, you can invoke Command using DataTrigger binded to IsSelected.
So you're trying to filter one collection (Products?) by the selected item from another collection (ProductCategories)?
If so, you seem to be over thinking this slightly. Remove any 'IsSelected' concept from your ProductCategory class as this is display related and does not belong in your model. Then change the ProductCategories ItemsControl to a ListBox and bind the LsitBox.SelectedItem to a 'SelectedProductCategory' property in your view model as Mode=TwoWay, UpdateSourceTrigger=PropertyChanged. When the user selects an item in the ListBox, the 'SelectedProductCategory' setter will be called, at which point you can filter your second collection (remembering to call PropertyChanged if the collection doesn't support change notification).
Hope it helps.
I must handle SelectedValue property changing to refresh some dependent UI elements when a user selects some item in a ListBox. I use SelectedValue because I need to know a concrete value of the item, not an index in the ListBox (the index may be different under variuos circumstances) or something another. My ListBox is binded to a DataTable and SelectedValue contains ID of a row in the table.
The problem is that when I try to get SelectedValue of the ListBox within SelectionChanged event handler, I receive a prior value, not the current! So, after I spent about a hour searching for ways of solving this problem, I noted that it is relatively well-known, but solutions I've seen do not seem to be very clear. Nevertheless, I "compiled" few ideas I have encountered to the next working snippet of code:
((DataRowView)this.LISTBOXNAME.SelectedItem)["ID"]
where this is my current window and SelectedItem may be casted to DataRowView as the ListBox is binded to a DataTable as I've mentioned before. This line of code gives a proper value of the selected ListBoxItem.
But anyway, I still want to know how to make SelectedValue get proper value directly? Is it possible? Or, maybe, must I use another event (not SelectionChanged)? And if it is impossible, can somebody explain me the way of thinking of kind guys from Microsoft and why that property has such a feature?
SelectedValueChanged event works fine for getting the correct SelectedValue property, so I think the issue may be with how your listbox is setup.
You say you have it bound to a DataTable, so the items in your collection are DataRowView objects.
If you set SelectedValuePath to something like "Id", then the SelectedValue property will attempt to set the SelectedValue to DataRowView.Id, which I don't think is a valid property.
Your two alternatives here are to either
Build a collection of objects with proper properties to use for the SelectedValue
<ListBox ItemsSource="{Binding MyCollection}"
SelectedValue="{Binding SelectedId}"
SelectedValuePath="Id" ... />
where MyCollection is a collection of objects that each contain an .Id property.
Or use SelectedItem instead of SelectedValue, and work with your DataRowView objects as you are now. SelectedItem will be set to the selected item in your collection, which is of type DataRowView, so the code you have posted is how it is accessed.
((DataRowView)this.LISTBOXNAME.SelectedItem)["ID"]
Of the two, the first approach is usually preferred for WPF.
Edit: Here's an answer to your question in the comments below since it was too long to fit in a comment.
A ListBox is meant to be bound to a collection of items. When you set the ItemsSource to a DataTable, you are really binding to a collection of DataRowView objects.
There are 3 ways to get selected item from here: SelectedItem, SelectedIndex, and SelectedValue.
SelectedItem returns you the object that is selected. In this case, that's the DataRowView object, which is why you can cast it to a DataRowView.
SelectedIndex returns you the index of the selected item within the data source.
SelectedValue can only be used if you have also set the SelectedValuePath property. SelectedValuePath tells WPF which property on each data object contains the "Value" of the item, so if you set it to something like "Id", it will try to find the .Id property on each object. In your case, there is no valid property on object DataRowView that would contain your Id column data, so this doesn't work.
Hope that answers your question :)
I have a WPF application with a ListBox (called listMyItems) which is successfully bound to a class of MyItems that I created. I have a List of MyItems called currentMyItems which is then assigned as ItemSource to the ListBox. It all works fine, if I add an item to the currentMyItems it pops up on the list, etc.
The problem occurs when I try to remove the selected item in the ListBox. This is the code that I use:
currentMyItems.Remove((MyItem)listMyItems.SelectedItem);
The item disappears from the ListBox but the next time I update it, it pops back up as it was never deleted. Any tips?
I think you may be confused about how data binding works. When you bind a property, you are telling WPF to go look somewhere else for the value of that property.
When you bind the ListBox.ItemsSource property to currentMyItems, you are telling WPF to go look at the currentMyItems list to find its list of items. If currentMyItems is an ObservableCollection instead of a List<T>, then the UI will automatically receive a notification to update the bound value when you add or remove an item from the collection.
Based on what you say in the question, it sounds like you you have two collections, one of which is bound, and the other which is used to recreate the first collection anytime a change occurs. All that is not needed.
Just create one ObservableCollection<MyItem>, bind it to the ListBox.ItemsSource property, and then add or remove items from that single collection. It should work as you would expect.
<ListBox x:Name="listMyItems" ItemsSource="{Binding MyItems}" />
and
MyItems.Add((MyItem)listMyItems.SelectedItem)
MyItems.Remove((MyItem)listMyItems.SelectedItem)
If you're interested, I also have some beginner articles on my blog for WPF users who are struggling to understand the DataContext. You may want to check out Understanding the change in mindset when switching from WinForms to WPF and What is this “DataContext” you speak of?
If you bound it correctly to an ObservableCollection and currentMyItems is that collection. Than it means that you must have reloaded currentMyItems in meantime.
Also consider binding the SelectedItem property of your ListView - your view model doesn't have to know about the view at all.
Your source collection must be modufy (inherit from IList or ICollection). If your source collection does not support this method of your interface Remove, you can't remove item from source.
So, when you want to remove item you must cast ItemsSource to IList or ICollection:
var source = listbox.ItemsSource as IList ?? listbox.ItemsSource as ICollection;
and then check:
if (source == null) return;
then:
listbox.SelectedItems.ForEach(source.Remove);
listbox.Items.Refresh();
Make the currentMyItems<MyItem> an ObservableColection<MyItem>. This way it will raise a property change whenever modified and the UI gets updated accordingly.
By using ObservableCollection you will automatically get updates on the UI.
You should use an ObservableCollection instead of List.
A good thing is to always use ObservableCollection instead of List when something to do with UI
I'm certain this has come up before, but I haven't been able to find the answer.
I made a basic ViewModel that contains a list of People (an array of Person) with a property called SelectedPerson, which naturally points to the currently selected Person in the list of People. I also have a ListBox and a TreeView that are databound to the ViewModel's People list.
What I'd like to do is to keep the ListBox's SelectedValue and TreeView's SelectedItem in sync with with the ViewModel's SelectedPerson. The idea is that no matter how the SelectedPerson is modified (through a control, through code, etc), all the controls should update themselves properly. I can get it to work with two ListBoxes, which is nice, but I can't get it to work with a ListBox and a TreeView because the TreeView's SelectedItem is readonly and apparently unavailable through XAML.
Where should I look to get ideas on making this work?
Also note that I'm trying to make this work in pure XAML. No code-behind as XAML files in my application can be loaded and changed dynamically.
Thanks!
You can Use Selector.IsSyncronizedWithCurrentItem.
You can bind both thye listbox and treeview to the same datasource and make sure that the IsSyncronized parameter is set to true. Then any changes to the current item in one will be reflected in the other.
More information can be found here:
link text
I asked around and the best solution I could find was here
http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/cc73893a-3383-4328-a002-ed8fb002a19d
It works for me but it's not the most optimal solution at this point.