Can not change the property of an object after initial binding - c#

I got stuck on a problem. In the project I am working on I have to populate one column of ListView with cheboxes and another one with comboboxes. The following is the data model that I am using as an ObservableCollection to bind it to a listview. Works really well!
public class PointDataMainListView
{
public string CheckBoxName { get; set; }
public ObservableCollection<string> ComboBoxItems{ get; set; }
public Visibility visibility { get; set; }
}
Except I have a hard time changing the properties of the combobox itself. In particular the visibility property.
The following is the data template i am using for the combo box
<DataTemplate x:Key="ComboBoxCell">
<ComboBox x:Name="ComboBox"
ItemsSource="{Binding ComboBoxItems}"
Width="100"
Visibility="{Binding visibility}"/>
</DataTemplate>
When populating the listview for the first time or adding a new item to a listview visibility could be set no problem. When visibility inside my ObservableCollection < PointDataMainListView > is changed for the item already displayed nothing is happening.
One of the solution I was looking into is trying to itterate through a list view items to try and get a reference to the actual combobox to change it's property. That said, I believe there must be a more elegant solution to achieve the desired results. Thank you for any help.

Your class needs to implement INotifyPropertyChanged and your properties setters need to invoke the PropertyChanged method.

Related

Binding multiple ComboBoxes to the same ItemsSource causes problems

I have 2 ComboBoxes whose ItemsSource is bound to the same ObservableCollection:
public ObservableCollection<MyType> MyTypeCollection { get; set; }
I have defined 2 different SelectedItem properties which in turn are bound to the correct ComboBox.
public MyType MySelectedItem1 { get; set; }
public MyType MySelectedItem2 { get; set; }
Whenever I select an item in one of the ComboBoxes, both SelectedItem properties defined in my class are set to that selection. Both ComboBoxes are also set visually to that value.
Why is this?
I tried several things like Mode=OneWay etc, but it's not working.
Here's my XAML (trimmed down for the question):
<ComboBox SelectedItem="{Binding MySelectedItem1}"
ItemsSource="{Binding MyTypeCollection, Mode=OneWay}"/>
<ComboBox SelectedItem="{Binding MySelectedItem2}"
ItemsSource="{Binding MyTypeCollection, Mode=OneWay}"/>
I'm guessing you have IsSynchronizedWithCurrentItem="True" on both ComboBox controls. Remove it from both, and that should solve your problem.
Setting IsSynchronizedWithCurrentItem="True" tells the ComboBox that it should keep its SelectedItem in sync with the CurrentItem in the underlying ICollectionView. Since you are binding directly to a collection, and not a collection view, both combo boxes are using the default collection view, which is a common instance shared across controls. When one of your combo boxes updates the collection view's selection, the other sees the change and updates its own selection to match it.

WPF: Bind to SelectedItem of row in DataGrid

I'm very new to WPF. I'm trying to bind to a property a row in a DataGrid so that when the row's clicked the property is set. The ItemsSource that's bound to the DataGrid is an ObservableCollection of objects of type Field.
I've tried to bind to the SelectedItem attribute on the DataGrid, but the property is not being called. I'm using almost identical code to bind to the SelectedItem of a ComboBox and this is working fine. Is there a difference that I don't know about?
<ComboBox ItemsSource="{Binding RecordTypes}" SelectedItem="{Binding SelectedRecordType}" ...
<DataGrid ItemsSource="{Binding Fields}" SelectedItem="{Binding SelectedField}" ...
In my ViewModel:
private Field SelectedField
{
get
{
return _selectedField;
}
set
{
_selectedField = value;
}
}
(I will use auto properties later, it's just currently set up like this so that I could break when the property was set).
I'm not sure if it makes a difference, but the DataGrid is composed of 2 DataGridTextColumns and a DataGridTemplateColumn, which contains a checkbox.
Does anyone have any ideas? I'd really appreciate any suggestions.
To confirm, the reason that I want to listen to the click of a row is so that I can have the checkbox be checked whenever a row is clicked. If there's a better solution for this then please let me know.
You need to make it a two-way binding:
SelectedItem="{Binding SelectedField,Mode=TwoWay}"
That propagates changes in the view (user selects an item, SelectedItem changes) back to the viewmodel ("SelectedField" property).
Also, as #KevinDiTraglia pointed out, you need to make sure that the viewmodel property SelectedField is public, not private, otherwise the binding will not be able to access the getter/setter.

Combo not updating using MVVM and XAML

I having trouble DataBinding a combo in XAML using the MVVM method.
I set the combo's source in the code behind like so:
AgesViewModel agesViewModel = new AgesViewModel();
comboAge.SelectedValuePath = "AgeID";
comboAge.DisplayMemberPath = "Age";
comboAge.ItemsSource = agesViewModel.GetAges();
And the XAML for the combo is:
<ComboBox x:Name="comboAge"
SelectedValue="{Binding AgeID}" />
The combo is part of a page with text controls and they all DataBind fine. The page DataContext is set to a ViewModel (carViewModel) which has a property called AgeID.
So when to combo items changed I want carViewModel.AgeID to be updated with the selected value.
Whenever I select an item from the combo nothing gets updated. What am I doing wrong??
Thanks in advance
I'm using XAML, C#4.5 and writing a windows store app in Visual Studio 2012.
If you want to follow the MVVM pattern, have the ComboBox's data also available in your carViewModel and bind to it.
In other words:
<ComboBox x:Name="comboAge" ItemsSource="{Binding MyAgeList}" SelectedValue="{Binding AgeID}" />
When changing the value in the ComboBox, this will also update the AgeID property.
Assuming AgeID is int (it can, of course, be whatever you want) then MyAgeList should be defined like this in carViewModel:
public List<int> MyAgeList {get; set;}
// Constructor
public CarViewModel()
{
MyAgeList = new AgesViewModel().GetAges();
}

WPF Combobox is not updating when collection changed in Model

WPF Combobox is not updating when collection changed in Model.
I am using ICollectionView for both DataGrid and ComboBox. DataGrid is updating when collection is changed in model, but ComboBox is not updating. Please let me know if there are any alternate ways to do this.
Here is the code
Model->
In Model I have
public ObservableCollection<Product> MyModelProducts
ViewModel->
DataGrid Collection
public ICollectionView MyViewModelProducts
{
get
{
return CollectionViewSource.GetDefaultView(MyModel.Instance.MyModelProducts);
}
}
ViewModel-ComboBox Collection
public ICollectionView MyViewModelListOfProducts
{
get
{
return CollectionViewSource.GetDefaultView(MyModel.Instance.MyModelProducts.Select(p => p.Category).Distinct().ToList<string>());
}
}
Code in View-->
<ComboBox ItemsSource="{Binding MyViewModelListOfProducts, Mode=OneWay}" />
Binding MyViewModelProducts to DataGrid
Binding MyViewModelListOfProducts to a ComboBox.
You have to refer to the selected product in offer to filter
Set IsSynchronizedWithCurrentItem to true in the DataGrid.
Raise a property change of MyViewModelListOfProducts when you want it to update. You subscribe the the MyViewModelProducts.CurrentChanged event and update it from there.
You can have a property DistinctCategories or so in the Product class that does that linq query (and is notified upon change, of course), and then bind the ComboBox to the MyViewModelProducts and point to this property - this I think is the preferred way, unless you think the distinct categories is has really no use in the model layer.

Silverlight Combobox loses visual value, but keeps selected value when the page it's on is hidden and reshown

I'm using a Silverlight 4.0 project that utilizes MVVM and we have a combobox that resides on a view and has its values and selected value bound to an observable collection of Organizations and a SelectedOrganization respectively (both values exist on the viewmodel). With our project the page that this control is on can be hidden or shown. The first load everything looks great but when you go to a different control (hide the tab with the control and then go back to it) the value that is currently selected in the combo box looks like it's blank, but when I debug, the selected value is still there.
The visual tree is getting recreated, but I have no idea why the combobox loses the text that should be in the box when the parent page is hidden and then re-shown. All other controls on the page behave correctly (autocompletetextbox, textblocks, textboxes, all of which have data bound to the viewmodel the same way).
Here's how the combobox is declared:
<ComboBox
SelectedItem="{Binding SelectedOrganization, Mode=TwoWay}"
ItemsSource="{Binding Organizations}"
DisplayMemberPath="Name"
Margin="5,0"
MinWidth="100" />
the Class for the organization is here:
[DataContract]
public class Organization
{
[DataMember]
public Guid OrganizationID { get; set; }
[DataMember]
public string Name { get; set; }
}
and the viewmodel has the following code for the bindings:
public Organization SelectedOrganization
{
get { return (Organization)GetValue("SelectedOrganization"); }
set
{
SetValue("SelectedOrganization", value);
}
}
public ObservableCollection<Organization> Organizations
{
get { return (ObservableCollection<Organization>)GetValue("Organizations"); }
set { SetValue("Organizations", value); }
}
What do I need to do to keep the selected value when I switch parent pages?
The problem is that I declared the ItemsSource AFTER the SelectedItem. Apparently this is a bug in Silverlight 3 and 4. The answer was discussed here Silverlight Combobox and SelectedItem.
Just a quick note on yet a SL3 bug.
I haven't reproduced this bug in a clean environment (since I'm getting quite tiered of reproducing SL ComboBox bug's...), but I experienced an issue with roughly this setup:
ItemsSource binds to property of type List on Object X.
SelectedItem binds to property of type String on Object X.
Object X implements INotifyPropertyChanged.
SelectedItem is set after ItemsSource in XAML code as the above post instructs.
ItemsSource is set to TwoWay BindingMode.
Behaviour: When the user TAB's from a textbox into the combobox, the combobox value is 'blanked', while the ViewModel maintains its value. The value is displayed again correctly when the user TAB's out of the ComboBox. Please note that the value is not blanked, if the combobox is merely clicked, or if it tabbed to from another combobox.
Solution: When stepping through the code with a debug'er it seems that SelectedItem is returned before ItemsSource, even though ItemsSource is declared before SelectedItem in the XAML code.
The solution was to change the ItemsSource from TwoWay BindingMode to OneWay BindingMode.
Probably this prevents some events from being fiered behind the scenes.
Br. Morten
Could be helpful if adding to previous post, I noticed that my selectedItem binding property must contain a conditional that avoid assing null value, because combobox control still wants to reset value once the control is hidden by scroll or whatever.
i.e. :
public string Month{
get {return _month;}
set {
if (value==null)
return;
_month = value;
}
}
Use this
<ScrollViewer Grid.Row="6" Grid.ColumnSpan="4" Height="190">
<sdk:DataGrid Name="datagridInvestigation"
AutoGenerateColumns="False" Width="650"
MinHeight="180" >
</sdk:DataGrid>
</ScrollViewer>
instead of
<sdk:DataGrid Name="datagridInvestigation"
AutoGenerateColumns="False" Width="650"
Height="180" ScrollViewer.HorizontalScrollBarVisibility="Auto" >

Categories

Resources