I have a ListView with a GridView (multiple columns) layout. Some column have converters which uses the current locale to prettify numbers, turn unix timestamps into datetime strings, or just translate an enum to a localized description of it.
The locale can be changed during runtime, so I need a way to rerun these converters as that happens. Note that the value itself of the binding has not changed, but the output of the converter may be different with a different locale.
What is the best way to do so? I don't want to iterate the whole collection of every affected list and call OnPropertyChanged. Is there a way to either force the ListView to refresh every binding, or just the bindings of some columns?
I found the answer:
ICollectionView view = CollectionViewSource.GetDefaultView(MyListView.ItemsSource);
view.Refresh();
You can force the ListView to update the ItemsSource binding with the following:
lview.GetBindingExpression(ListView.ItemsSourceProperty).UpdateTarget();
Using this same syntax, you could certainly get more specific, and force an update only on the bindings for specific columns, but depending on the number of rows in your ListView, you may not see a performance difference.
Related
so I want to populate a combobox items source with the contents on an enum (and obviously retrieve the values later on).
Populating works fine with either of the two following approaches but neither matches what I want to achieve.
comboBox.ItemsSource = Enum.GetValues(typeof(VirtualKey));
I can retrieve the values without issue using a simple (VirtualKey)comboBox.SelectedItem. The problem is, the names in the dropdown menu are all unreadable.
comboBox.ItemsSource = Enum.GetNames(typeof(VirtualKey));
Displays the names as intended but I can't retrieve the value like with the other instruction.
Any ideas how to solve the situation?
comboBox.ItemsSource = Enum.GetNames(typeof(VirtualKey));
Displays the names as intended but I can't retrieve the value like with the other instruction.
I don't know how are you getting the selected value, but for converting from enum value name to its value, you can use the Enum.Parse(Type, String) method.
Or you can bind the ComboBox.SelectedIndex to your enum variable for example using something like my EnumToIntConverter.
This puzzling behavior was also discussed here:
UWP - binding Enum differences
Even simple ToString() call overcomes this issue. For some reason however, some Windows Runtime enums in direct XAML binding show up with IReference.
I am making a WPF GUI where I have a datagrid with several columns. I would like to make cell type in one of the columns vary depending on the selection in another cell. A cell would need to swap between Text and ComboBox.
In the image below the datagrid can be seen. I want functionality where when user checks the IsConstant checkbox, then he can enter a constant numeric value, otherwise he would be presented with a ComboBox from which he could select an option he likes. The checkbox column is bound to a bool value in codebehind.
However I am not sure how and If this is possible. Any suggestions are welcome. Thanks.
I think the only way to achieve what you want is through the use of a DataGridTemplateColumn. You can define a custom template for this column type, which contains controls for each type of edit option you want to provide, with the visibility of each control switching depending on the conditions you have.
I did a search, and found This answer which deals with this very issue, with an example provided. I think you could probably make a simpler template than is given in this example, but the idea is the same.
Edit:
Here's an alternate example which uses a template selector (too long to post inline here).
I have a datagrid that is bound to a collection of my ViewModel. One of its column has values that are very specific to business requirements. On this column it can contain an alphanumeric characters.
For example I can have column values A1,A20,AA,AA12,AAA. Now I want to custom sort this values, say I want the anything with most letters should go first or etchetera. There is a default sorting with DataGrid but only do normal sorting.
My question is how would you implement this through MVVM? We can get away with this through subscribing to an event in code behind and re arrange the whole collection. However this is not what I want, I am looking for suggestions or solutions on how to approach this.
I found this link Sorting on datagrid column with binded data and converter that is attaching a property for a DataGrid but what I want to do is to attach a property to be updated every time a user click on this column. Is it possible to attach a property in a DataGrid Column?
Possible duplicate of : Sorting on datagrid column with binded data and converter but this is not using MVVM.
There are several strategies, but the most immediately accessible is to set up a DataGrid something like this...
<DataGrid ItemsSource="{Binding DriveList}" AutoGenerateColumns="False" >
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Name}" SortMemberPath="DriveType"/>
</DataGrid.Columns>
</DataGrid>
This example shows the grid binding to a list of drives on the host machine. The first column shows the information is bound to the property 'Name'. BUT when you click the column header, it will sort on a property which is not displayed, 'DriveType'. Strange example, but it works fine.
So in your app, you would amend your collection items to include a property that is not displayed, and populate it with values according to what you want. In the example in your question, you might use something like...
MySortString = MyName.ToString().Length;
And that will cause the sort to do what you are looking for, i.e., the longest value of 'MyName' will be first with shorter values after that. You have to repopulate 'MySortString' property every time you change sort methods or reload your data source.
This strategy is MVVM compliant because all you are doing in the VM is populating an additional property. Plus you can unit test it immediatly with Nunit or whatever.
I created an attached behavior which does this in a nice MVVM-friendly way:
WPF DataGrid CustomSort for each Column
Hopefully this addresses your problem.
I use SQLite3 to read data from a database and then display the results in a listBox, I would to ask if there is possibility to display the results in a listBox as columns in nice show without using DataGrid.
It is better to use ListView instead of listBox.
Also you can still use listbox for multicolumn purpose
Listbox is not designed to work with multiple columns. Any reason why you do not want to use a DataGrid?
In general a grid control is the most appropriate when dealing with items or records having multiple properties or fields to be shown in different columns, some people also use a ListView with the report/details style and several sub items one per each column.
In my experience when the final result is really a table/grid it is easier and simpler to use a grid instead of "forcing" a ListView to behave like a grid. ListView is not designed for that even if it can be used in a similar way.
I'm binding to an ienumerable(items) in my MainViewModel to display data. As i've described here before How to change the content in a datagrid or listview using MVVM, all i want to do is display different tables. My first approach was to use the normal datagrid and set the "AutoGenerateColumns" to true, so that the correct columns are displayed. As it turns out, performance was pretty bad so i switched to ListView and GridView, but since there is no "AutoGenerateColumns" available i need to somehow create and change the columns.
So how would you do it?
Have a look at this question for something that comes close to -- but is not -- auto-generation: WPF GridView with a dynamic definition.
Generally speaking, autogenerating means doing reflection on the ItemsSource, which can get messy since it needs to cover a huge number of possibilities correctly.