I'm not sure what I'm missing here, but I'm having trouble getting a checkbox to bind to a list properly. The rest of the properties of the list bind just fine, but the checkbox is having issues. Here's what I have:
In the class that serves as the template for each object in the list I have:
Property Process As New CheckBox
In the MainWindow_Loaded Event I have:
Dim ProcessCol As new DataGridCheckBoxColumn
ProcessCol.Header = "P?"
ProcessCol.IsReadOnly = False
...
InputGrid.ItemsSource = InputData 'Which is a list of my Order Allocation objects which contains the checkbox property
...
Dim ProcessBinding As New Binding("Process")
ProcessBinding.Mode = BindingMode.TwoWay
ProcessCol.Binding = ProcessBinding
...
InputGrid.Columns.Add(ProcessCol)
When I try to populate this collection and look at the items I get checkbox = nothing. I'm not sure what I'm missing here... I know I couldn't be too far off...
Edit: I changed the property to "new CheckBox" and now I get an initialzied checkbox object in the list item as "System.Windows.Controls.CheckBox Content: IsChecked:False which in this case should have been true. So maybe a step closer, but still not there.
I found an answer here: WPF: CheckBox in DataGrid
Technically not an answer to my original question, but it works. Rather than a checkbox property in my class I now have a boolean property. The column is still created as a checkbox column. It works.
If a column can be bound to a chebox property of a list I'd still be interested in hearing that, but for me this solution works.
Related
Below is the code behind in my view model:
private DataRow selectedErrorRow;
public DataRow SelectedErrorRow
{
get { return selectedErrorRow; }
set { selectedErrorRow = value; base.RaisePropertyChanged("SelectedErrorRow"); }
}
Then this in my view:
<DataGrid SelectedItem="{Binding SelectedErrorRow,Mode=TwoWay}"
The binding somewhat works... It "gets" the value when the datagrid is drawn but it never sets it when a new value is selected/highlighted.... Any ideas?
Note the item source for the datagrid is a DataTable.
EDIT:
The Datagrid is in a PopUp, when the datagrid gets drawn it will get the binded value (null). However once I selected/highlight a row it will NOT 'set' anything. It will however 'set' the binded value null when its redrawn (the popup is open, i selected a row, close it,and reopen it). The thing is It never sets the value to anything but null, and it only sets it during the secound time its drawn.
I needed to change what I was binding to. It needs to bind to a DataRowView and not a DataRow.
I had this issue previously and figured it out myself.
It is not intuitive to know what is the issue since you cannot see the real value in debug but when you data bind a DataTable on a datagrid at first you think it has a DataTable type as source right ? Well you are wrong if you think that.
Actually the datagrid or the binding (i still don't know where it happen as i only see DataTable on my side) does a cast/convert of DataTable object like DataTable.AsDataView() to convert it to a DataView by itself so the selected item make sense to me to be DataRowView.
I know it's old question but this might shed light to those who get here and also look to set value as data source especially converters
Try this:
DataGrid SelectedItem="{Binding Path=SelectedErrorRow,Mode=TwoWay}
This should solve your problem.
I am using a wpf treeview and binding the ItemsSource to an IEnumerable of my ViewModel that has an IsChecked Property. I am binding a checkbox to this value with a Mode of TwoWay. I can see when I step through the program that it is setting this value properly on my ViewModel when I check the checkbox.
I then have a Menu Item that "Runs Checked". In this method I have a foreach loop that runs through the ItemsSource as IEnumerable of ViewModel looking for IsChecked = true to queue up the checked items to be run by a separate program. As such:
foreach (AccountViewModel account in tvClientList.ItemsSource as IEnumerable<AccountViewModel>)
{
if (account.IsChecked)
{
context.Queues.InsertOnSubmit(new Queue {Id = account.Id});
}
}
However, account.IsChecked is always false. Why is this?
i would check the following.
does the setter of AccountViewModel.Ischecked is called when clicking the treeview checkbox. if no - then thats the problem if yes you should look at your collection bindings.
debug your foreach and check wether the treeviewitemssource is the collection you expect.
maybe you can post your bindings, if that all no help.
ps: dont access your View controls directly if you use viewmodels/mvvm.
Just for anyone else encountering this issue. ItemsSource returns a new set of data, Items, however contains the current set of data.
I have a combobox and set the itemssource to a list of strings:
private List<string> list = new List<string>();
...
ComboBox cbo = new ComboBox();
cbo.ItemsSource = list;
The combobox gets filled successful on startup.
But when the list is changed, the combobox doesn't update its items, BUT only when I expanded the items before, else the combobox gets updated...
Also weird: when I trace the count of items of the combobox, the count is the correct updated number, but the displayed items aren't.
Somebody has an idea, what's going on here?
EDIT: See solution in comments to post of Robert
I guess you need to use ObservableCollection instead of List, because ComboBox needs to be notified whenever the collecion changes.
Change List into ObservableCollection.
Use ObservalbeCollection. It has inbuilt mechanism to notify and change in the number of items.
A control has an ItemsSource Property of type IEnumerable. If I try to add items to Items collection when ItemsSource is set I get an error "Operation is not valid while ItemsSource is in use. Access and modify elements with ItemsControl.ItemsSource instead."
A method for Removing Items is present here:
WPF - Best way to remove an item from the ItemsSource
However I cannot find a method to (based on the same interface) to add a new Item. The AddNew method does not take any arguments. From the sample at : http://msdn.microsoft.com/en-us/library/system.componentmodel.ieditablecollectionview.canaddnew.aspx I felt this to be the correct code:
IEditableCollectionView items = paneToDropInto.Items;
if (items.CanAddNew)
{
object newitem = items.AddNew();
newitem = contentToTransfer;
items.CommitNew();
}
However it does not work. It does add the new item. But it is a blank Item. Note contentToTransfer.
Figured it out. As pointed out by Tom and Djerry +1 both (thanks). I am just re referencing the new item which will not cause the original new item generated by AddNew to be saved (very stupid of me).
However there is another interface I can use (and did use):
IEditableCollectionViewAddNewItem items = paneToDropInto.Items;
if (items.CanAddNewItem)
{
object newitem = items.AddNewItem(contentToTransfer);
}
I have a listbox with silverlight 4. I have the list bound to a list of objects.
1.) The SelectedValue property is bound to a public property of the viewmodel called Current. How do i clear the selection? I have tried setting the value of Current to null. Well, this clears the selection however it also breaks binding in the edit form which has a combobox bound to a property of 'Current'. Textboxes which are bound to Current.FirstName etc. are working ok however the comboboxes do not function after I set the Current object to null.
2.) how do i load the form without the first item being selected?
Found a work around for this bug in Silverlight:
// Bug in SL listbox prevents SelectedIndex = -1 from unselected.
// Workaround is to use DispatcherBeginInvoke to do it async. Found
// work around here:
// http://sharplogic.com/blogs/rdavis/PermaLink,guid,2f5bbfa1-4878-490f-967d-bf00bc04dfde.aspx
Dispatcher.BeginInvoke(() => { QuickItemsListBox.SelectedIndex = -1; });
More details here:
http://sharplogic.com/blogs/rdavis/PermaLink,guid,2f5bbfa1-4878-490f-967d-bf00bc04dfde.aspx
Not sure when it was fixed but VoodooChild's answer works now in Silverlight 5. Passing this along in case others are looking.
yourCB.selectedIndex = -1;
Try:
yourCB.SelectedIndex = -1;