WPF Binding in ComboBox with UserControl list - c#

In two combobox A and B.
A's ItemsSource is Custom list. and B's ItemsSource is UserControl list.
When manually setting the SelectedItem, A combobox works well, but B combobox UI do not show the selected Item. (In debugging, SelectedItem's value mapping is right, but the combobox B's UI do not be changed.)
All the other structure is same between A and B. What is the reason?
MainWindow.xaml
...
<ComboBox ItemsSource="{Binding FruitList}" SelectedItem="{Binding SelectedFruit}"
DisplayMemberPath="FruitName" />
<Button Content="Button" HorizontalAlignment="Left"
VerticalAlignment="Top" Width="75" Click="Button_Click"/>
<ComboBox ItemsSource="{Binding UserControlList}" SelectedItem="{Binding SelectedUserControl}" DisplayMemberPath="ItemName" />
<Button Content="Button" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Click="Button_Click2"/>
</Grid>
MainWindow.xaml.cs
public partial class MainWindow : Window, INotifyPropertyChanged
{
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
FruitList.Add(f1);
FruitList.Add(f2);
FruitList.Add(f3);
UserControlList.Add(u1);
UserControlList.Add(u2);
UserControlList.Add(u3);
}
Fruit f1 = new Fruit { FruitName = "Apple" };
Fruit f2 = new Fruit { FruitName = "Banana" };
Fruit f3 = new Fruit { FruitName = "Lemon" };
MyUserControl u1 = new MyUserControl { ItemName = "Apple" };
MyUserControl u2 = new MyUserControl { ItemName = "Banana" };
MyUserControl u3 = new MyUserControl { ItemName = "Lemon" };
ObservableCollection<Fruit> _FruitList = new ObservableCollection<Fruit>();
public ObservableCollection<Fruit> FruitList
{
get { return _FruitList; }
set
{
_FruitList = value;
OnPropertyChanged();
}
}
Fruit _SelectedFruit;
public Fruit SelectedFruit
{
get { return _SelectedFruit; }
set
{
_SelectedFruit = value;
OnPropertyChanged();
}
}
ObservableCollection<MyUserControl> _UserControlList = new ObservableCollection<MyUserControl>();
public ObservableCollection<MyUserControl> UserControlList
{
get
{
return _UserControlList;
}
set
{
_UserControlList = value;
OnPropertyChanged();
}
}
MyUserControl _SelectedUserControl;
public MyUserControl SelectedUserControl
{
get { return _SelectedUserControl; }
set
{
_SelectedUserControl = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
void OnPropertyChanged([CallerMemberName] string caller = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(caller));
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
this.SelectedFruit = f3;
}
private void Button_Click2(object sender, RoutedEventArgs e)
{
this.SelectedUserControl = u3;
}
}
public class Fruit
{
public string FruitName { get; set; }
}
}
UserControl
public partial class MyUserControl : UserControl
{
public MyUserControl()
{
InitializeComponent();
}
public string ItemName { get; set; }
}

This is not the good way of achieving this. Better define the ItemTemplate for the combobox to have the UserControl in it like:
<ComboBox ItemsSource="{Binding ItemList}" SelectedItem="{Binding SelectedItem}" >
<ComboBox.ItemTemplate>
<DataTemplate>
<myControls:MyUserControl/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
and define the class Item
public class Item
{
public string ItemName { get; set; }
}
ObservableCollection<Item> _ItemsList = new ObservableCollection<Item>();
public ObservableCollection<Item> ItemsList
{
get
{
return _ItemsList ;
}
set
{
_ItemsList = value;
OnPropertyChanged();
}
}
Here DataContext of your UserControl will be Item object. you can bind the ItemName within you user control to show it in anyway you want.
in your user control you can have:
<TextBlock Text="{Binding ItemName}"></TextBlock>

Since you have asked "What is the reason?":
The reason why the second combo box does not show any selection is that ComboBox handles items of type ContentControl specially. In the read-only selection box, it is not the ContentControl that is used to display the value, but the content of the ContentControl. Since a UserControl is a ContentControl, the content of the UserControl is displayed inside the selection box, and therefore you have lost the data context of the UserControl; in the end, an empty string is displayed even though SelectedItem contains a reference to the UserControl that still has a valid data context. (As far as I know this behavior is undocumented; but you can see that it works like this by examining the ComboBox's code on http://referencesource.microsoft.com/#PresentationFramework/src/Framework/System/Windows/Controls/ComboBox.cs, especially the UpdateSelectionBoxItem() method).
By setting IsEditable="True" on the second ComboBox, you can see that everything works fine if the combo box has no read-only selection box.
Therefore, you generally should avoid adding UI elements to combo boxes, especially if you are using the DisplayMemberPath property, i.e. if you never want to actually display the UI element.
The recommended way to display ComboBox items with non-standard appearance (e.g. with UserControls) is described in the answer of #nit.
If you, however, insist on passing a UserControl item list to the ComboBox, you might remove DisplayMemberPath and use something like this:
<ComboBox ItemsSource="{Binding UserControlList}" SelectedItem="{Binding SelectedUserControl}" >
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding ItemName}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Furthermore, in the constructor of your UserControl, you must place this line:
((FrameworkElement) Content).DataContext = this;
This is necessary to make sure that the correct data context is available in the read-only selection box, which only contains the content of the user control, not the user control itself.
Please note, that with the above example, the drop-down list contains text only (i.e. the item names), but the selection box will contain the fully rendered user control.

Related

Set DataContext for multiple controls with XAML

I have different groups of controls bound to different categories of ViewModel classes.
The ViewModels are
MainViewModel
VideoViewModel
AudioViewModel
Question
How can I set the DataContext with XAML instead of C#?
1. I tried adding DataContext="{Binding VideoViewModel}" to the ComboBox XAML, but it didn't work and the items came up empty.
2. I also tried grouping all the ComboBoxes of a certain category inside a UserControl with the DataContext:
<UserControl DataContext="{Binding VideoViewModel}">
<!-- ComboBoxes in here -->
</UserControl>
3. Also tried setting the <Window> DataContext to itself DataContext="{Binding RelativeSource={RelativeSource Self}}"
Data Context
I'm currently setting the DataContext this way for the different categories of controls:
public MainWindow()
{
InitializeComponent();
// Main
this.DataContext =
tbxInput.DataContext =
tbxOutput.DataContext =
cboPreset.DataContext =
MainViewModel.vm;
// Video
cboVideo_Codec.DataContext =
cboVideo_Quality.DataContext =
tbxVideo_BitRate.DataContext =
cboVideo_Scale.DataContext =
VideoViewModel.vm;
// Audio
cboAudio_Codec.DataContext =
cboAudio_Quality.DataContext =
tbxAudio_BitRate.DataContext =
tbxAudio_Volume.DataContext =
AudioViewModel.vm;
}
XAML ComboBox
<ComboBox x:Name="cboVideo_Quality"
DataContext="{Binding VideoViewModel}"
ItemsSource="{Binding Video_Quality_Items}"
SelectedItem="{Binding Video_Quality_SelectedItem}"
IsEnabled="{Binding Video_Quality_IsEnabled, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Width="105"
Height="22"
Margin="0,0,0,0"/>
Video ViewModel Class
public class VideoViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = delegate { };
private void OnPropertyChanged(string prop)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(prop));
}
}
public VideoViewModel() { }
public static VideoViewModel _vm = new VideoViewModel();
public static VideoViewModel vm
{
get { return _vm; }
set
{
_vm = value;
}
}
// Items Source
private List<string> _Video_Quality_Items = new List<string>()
{
"High",
"Medium",
"Low",
};
public List<string> Video_Quality_Items
{
get { return _Video_Quality_Items; }
set
{
_Video_Quality_Items = value;
OnPropertyChanged("Video_Quality_Items");
}
}
// Selected Item
private string _Video_Quality_SelectedItem { get; set; }
public string Video_Quality_SelectedItem
{
get { return _Video_Quality_SelectedItem; }
set
{
if (_Video_Quality_SelectedItem == value)
{
return;
}
_Video_Quality_SelectedItem = value;
OnPropertyChanged("Video_Quality_SelectedItem");
}
}
// Enabled
private bool _Video_Quality_IsEnabled;
public bool Video_Quality_IsEnabled
{
get { return _Video_Quality_IsEnabled; }
set
{
if (_Video_Quality_IsEnabled == value)
{
return;
}
_Video_Quality_IsEnabled = value;
OnPropertyChanged("Video_Quality_IsEnabled");
}
}
}
You can instantiate an object in xaml:
<Window.DataContext>
<local:MainWindowViewmodel/>
</Window.DataContext>
And you could do that for your usercontrol viewmodels as well.
It's more usual for any child viewmodels to be instantiated in the window viewmodel. Exposed as public properties and the datacontext of a child viewmodel then bound to that property.
I suggest you google viewmodel first and take a look at some samples.
I'm not sure if this is the correct way, but I was able to bind groups of ComboBoxes to different ViewModels.
I created one ViewModel to reference them all.
public class VM: INotifyPropertyChanged
{
...
public static MainViewModel MainView { get; set; } = new MainViewModel ();
public static VideoViewModel VideoView { get; set; } = new VideoViewModel ();
public static AudioViewModel AudioView { get; set; } = new AudioViewModel ();
}
I used Andy's suggestion <local:VM> in MainWindow.xaml.
<Window x:Class="MyProgram.MainWindow"
...
xmlns:local="clr-namespace:MyProgram"
>
<Window.DataContext>
<local:VM/>
</Window.DataContext>
And used a UserControl with DataContext set to VideoView, with ComboBoxes inside.
Instead of a UserControl, can also just use VideoView.Your_Property_Name on each binding.
<UserControl DataContext="{Binding VideoView}">
<StackPanel>
<ComboBox x:Name="cboVideo_Quality"
ItemsSource="{Binding Video_Quality_Items}"
SelectedItem="{Binding Video_Quality_SelectedItem}"
IsEnabled="{Binding Video_Quality_IsEnabled, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Width="105"
Height="22"
Margin="0,0,0,0"/>
<!-- Other ComboBoxes with DataContext VideoView in here -->
</StackPanel>
</UserControl>
Then to access one of the properties:
VM.VideoView.Video_Codec_SelectedItem = "x264";
VM.VideoView.Video_Quality_SelectedItem = "High";
VM.AudioView.Audio_Codec_SelectedItem = "AAC";
VM.AudioView.Audio_Quality_SelectedItem = "320k";
Others have obviously provided good answers, however, the underlying miss of your binding is your first set of DataContext = = = = = to the main view model.
Once you the main form's data context to the MAIN view model, every control there-under is expecting ITS STARTING point as the MAIN view model. Since the MAIN view model does not have a public property UNDER IT of the video and audio view models, it cant find them to bind do.
If you remove the "this.DataContext =", then there would be no default data context and each control SHOULD be able to be bound as you intended them.
So change
this.DataContext =
tbxInput.DataContext =
tbxOutput.DataContext =
cboPreset.DataContext =
MainViewModel.vm;
to
tbxInput.DataContext =
tbxOutput.DataContext =
cboPreset.DataContext =
MainViewModel.vm;

IsTextSearchEnabled not working properly on ComboBox

What I'm trying to do
I'm trying to implement the AutoComplete feature on ComboBox without using WpfToolkit. If I'm not wrong, the ComboBox should support the AutoComplete for a simple string item so for example:
<ComboBox IsEditable="True">
<ComboBoxItem>Apple</ComboBoxItem>
<ComboBoxItem>Banana</ComboBoxItem>
<ComboBoxItem>Pear</ComboBoxItem>
<ComboBoxItem>Orange</ComboBoxItem>
</ComboBox>
Current object implementation
actually my ComboBox bound a custom object called CheckedListItem, this object have the following structure:
public class CheckedListItem<T> : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private bool isChecked;
private T item;
public CheckedListItem() { }
public CheckedListItem(T item, bool isChecked = false)
{
this.item = item;
this.isChecked = isChecked;
}
public T Item
{
get { return item; }
set
{
item = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Item"));
}
}
public bool IsChecked
{
get { return isChecked; }
set
{
isChecked = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("IsChecked"));
}
}
}
this class show as ComboBoxItem a CheckBox near the Text of the Item, similar to:
[] Item1
[] Item2
...
where [] is the Checkbox.
ComboBox structure
The ComboBox look like this:
<ComboBox IsEditable="True" ItemSource={Binding Countries}/>
where Countries is a List of CheckedListItem<Country>, the object country is implemented in this way:
public class Country
{
public string Name { get; set; }
}
the problem on this code is that when I type some text in the ComboBox this doesn't do anything, but should display on the items that contains the string typed.
What I tried so far
I tried to fix this by implementing a PreviewTextInput event, actually I managed in this way:
MyComboBox.IsDropDownOpen = true;
CountryMenuComboBox.ItemsSource = Countries.Where(c => c.Item.Name.Contains(e.Text)).ToList();
but this doesn't working correctly, cause if I type "England", the ItemSource display even all Items.
Any idea to fix this?
Thanks.
Try to set the TextSearch.TextPath property to "Item.Name":
<ComboBox IsEditable="True" ItemsSource="{Binding Countries}"
TextSearch.TextPath="Item.Name">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<CheckBox IsChecked="{Binding Item.IsChecked}" />
<TextBlock Text="{Binding Item.Name}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>

ListBox with DataTemplate recognize SelectedItem

I have a ListBox with a simple DataTemplate, a CheckBox, and a TextBox.
If the user checks a CheckBox I want to get this changed item, like the property SelectedItem of the ListBox.
How can I get the element from List2, which has changed?
MyListItem:
public class MyListItem2 : ReactiveObject
{
private string _name;
public string Name
{
get { return _name; }
set
{
this.RaiseAndSetIfChanged(ref _name, value, "Name");
}
}
private bool _isMarked;
public bool IsMarked
{
get { return _isMarked; }
set
{
this.RaiseAndSetIfChanged(ref _isMarked, value, "IsMarked");
}
}
}
View:
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DataTemplate.Views.MainWindow"
xmlns:viewsmodels="clr-namespace:DataTemplate.ViewModels;assembly=DataTemplate"
xmlns:dt="clr-namespace:DataTemplate;assembly=DataTemplate"
Title="DataTemplate" Width="700">
<Window.DataContext>
<viewsmodels:MainWindowViewModel />
</Window.DataContext>
<Grid ColumnDefinitions="250">
<ListBox Grid.Column="1" Items="{Binding List2}">
<ListBox.ItemTemplate>
<DataTemplate DataType="dt:MyListItem2">
<Grid ColumnDefinitions="50*,50*">
<CheckBox Grid.Column="0" Content="Mark" IsChecked="{Binding IsMarked}"/>
<TextBox Grid.Column="1" Text="{Binding Name}"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
ViewModel:
public class MainWindowViewModel : ReactiveObject
{
public ObservableCollection<MyListItem2> List2 { get; set; }
public MainWindowViewModel()
{
List2 = new ObservableCollection<MyListItem2>();
Random rand = new Random();
for (int i = 0; i < rand.Next(1, 20); i++)
{
MyListItem2 mli = new MyListItem2();
mli.Name = "ListItem" + i;
mli.IsMarked = false;
mli.PropertyChanged += ItemChanged;
List2.Add(mli);
}
}
private void ItemChanged(object sender, PropertyChangedEventArgs e)
{
var item = sender as MyListItem2;
Console.WriteLine(string.Format("changed: {0} {1}", item.Name, item.IsMarked));
}
}
I can see two ways:
Since you are using MVVM, implement the INotifyPropertyChanged interface on the MyListItem2 class (Microsoft Reference on INotifyPropertyChanged implementation). Raise the property change event when the IsMarked value is set/changed, then wire into the PropertyChanged event handler of the item to determine when it is changed. . OR
If you have codebehidn, add a "Checked" and/or "Unchecked" event handler on the checkbox itself from the XAML. Shown below.
CheckBox Grid.Column="0" Content="Mark" IsChecked="{Binding IsMarked}"/>
Checked="IsMarked_Checked"
Codebehind
public void IsMarked_Checked(object sender, RoutedEventArgs e)
{
var ck = sender As Checkbox;
if (ck == null)
{
return;
}
// do whatever you need to here using the datacontext of the Checkbox
}
If you want to know when a check box is checked/unchecked by the user you will need to trigger on the event from the checkbox.
Use something like this:
private void MyCheckBox_Checked(object sender, RoutedEventArgs e)
{
//check IsChecked of MyCheckBox here
}
Try setting binding Mode:
SelectedItem="{Binding SelectedItem, Mode=TwoWay}"

set SelectedItem of ComboBox to value of item in ListCollectionView

I have a ListCollectionView which holds a bunch of Items of object Scene. One of the properties in Scene is Location.
When I navigate through the ListCollectionView I want to set the value of the Location property as SelectedItem in a comboBox in the View. Each time I go to a different item in the ListCollectionView I want to show the new location as SelectedItem in the comboBox.
I know how to make this work in a regular TextBox and TextBlock, but not in a ComboBox.
ViewModel
public ListCollectionView SceneCollectionView { get; set; }
private Scene CurrentScene
{
get { return SceneCollectionView.CurrentItem as Scene; }
set
{
SceneCollectionView.MoveCurrentTo(value);
RaisePropertyChanged();
}
}
View
<ComboBox SelectedItem="{Binding SceneCollectionView/Location, UpdateSourceTrigger=PropertyChanged}" ItemsSource="{Binding AllLocations}}"/>
For textboxes following works perfectly, but not for comboBoxes
<TextBox Text="{Binding SceneCollectionView/Location, UpdateSourceTrigger=PropertyChanged}"/>
Any Idea how I can get the same behavior in for SelectedItem in ComboBox. I'm fairly new to coding in c#
If all Locations defined in the supplied collection for your ListCollectionView exist in the Locations defined in your AllLocations property, then your code should work.
For example the following code along with the ComboBox you currently defined in your Xaml works as you expect:
Xaml:
<Grid>
<ComboBox SelectedItem="{Binding SceneCollectionView/Location, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding AllLocations}"/>
<TextBox Text="{Binding SceneCollectionView/Location, UpdateSourceTrigger=PropertyChanged}"/>
<Button Content="SelectNext" Click="Button_Click"/>
</Grid>
Code:
public ListCollectionView SceneCollectionView { get; set; }
public List<string> AllLocations { get; set; }
public MainWindow()
{
InitializeComponent();
DataContext = this;
var scenes = new List<Scene>();
scenes.Add(new Scene { Location = "location1"});
scenes.Add(new Scene { Location = "location2"});
scenes.Add(new Scene { Location = "location3" });
SceneCollectionView = new ListCollectionView(scenes);
AllLocations = new List<string> { "location1", "location2", "location3" };
}
private void Button_Click(object sender, RoutedEventArgs e)
{
SceneCollectionView.MoveCurrentToNext();
}
In the above code, when you click the Button, Both ComboBox.SelectedItem and TextBox.Text changes to the next Item.Location defined in your SceneCollectionView.

Getting Items From Within ItemsControl (Understanding DataContext)

I am populating an ItemsControl with various elements, including Buttons and ComboBox elements. Accessing and populating the elements is simple, but I'm stuck on how to detect and associate which Item in the ItemsControl the ComboBox (or Button) belongs to.
To help illustrate the problem, consider the following basic UI:
Now, when I use the ComboBox or Button I want to be able to associate that use only with the ItemControl Item it's a part of. However, currently, if I select an item in the ComboBox every ComboBox in the ItemsControl will reflect that change.
I can capture the SelectedItem in the below ListBox, but ideally, I would like to be able to display both the SelectedItem and which ItemControl Item it came from. For instance, ComboBoxItem1, My First Property - From Item (1).
I am strictly adhering to MVVM principals, and consequently, I am not looking for any solutions using code-behind.
TL;DR
I know the code can become unwieldy. I believe the above description is adequate to state my problem, but I am including the basic boiler plate code below in case it's helpful in posting an answer. (Obviously, I have implemented INotifyProperty and ICommand elsewhere):
MainWindowView.xaml
<ItemsControl Width="300" Height="200" ItemsSource="{Binding MyObservableCollection}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Black" BorderThickness="2" Margin="10">
<StackPanel Margin="0,10,0,10">
<TextBlock Margin="10,0,0,0" Text="{Binding MyProperty}" FontWeight="Bold"/>
<ComboBox Width="270" Text="myBox" ItemsSource="{Binding DataContext.ComboOptions, RelativeSource={RelativeSource AncestorType=ItemsControl}}" DisplayMemberPath="ListItem" SelectedItem="{Binding DataContext.SelectedItem, RelativeSource={RelativeSource AncestorType=Window}}"/>
<RadioButton Width ="270" Content="Button1" Command="{Binding DataContext.GetButtonCommand, RelativeSource={RelativeSource AncestorType=ItemsControl}}" CommandParameter="Button1" Style="{DynamicResource {x:Type ToggleButton}}"/>
</StackPanel>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
MyComboBoxOptionsViewModel.cs
public class MyComboBoxOptionsViewModel : ObservableObject
{
private MyComboBoxOptionsModel _myComboBoxOptions = new MyComboBoxOptionsModel();
public MyComboBoxOptionsViewModel(MyComboBoxOptionsModel _myComboBoxOptions)
{
this._myComboBoxOptions = _myComboBoxOptions;
}
public string ComboBoxOption
{
get { return _myComboBoxOptions.ComboBoxOption; }
set
{
_myComboBoxOptions.ComboBoxOption = value;
RaisePropertyChangedEvent("ComboBoxOption");
}
}
}
MyComboBoxOptionsModel.cs
public class MyComboBoxOptionsModel
{
public string ComboBoxOption { get; set; }
}
MainWindowViewModel.cs
public class MainWindowViewModel : ObservableObject
{
private ObservableCollection<string> _messages = new ObservableCollection<string>();
private ObservableCollection<MyViewModel> _myObservableCollection = new ObservableCollection<MyViewModel>();
private List<MyComboBoxOptionsViewModel> _comboOptions = new List<MyComboBoxOptionsViewModel>();
private MyComboBoxOptionsViewModel _selectedItem = new MyComboBoxOptionsViewModel(null);
public MainWindowViewModel()
{
_myObservableCollection.Add(new MyViewModel(new MyModel { MyProperty = "My First Property" }));
_myObservableCollection.Add(new MyViewModel(new MyModel { MyProperty = "My Second Property" }));
_comboOptions.Add(new MyComboBoxOptionsViewModel(new MyComboBoxOptionsModel { ComboBoxOption = "Option1" }));
_comboOptions.Add(new MyComboBoxOptionsViewModel(new MyComboBoxOptionsModel { ComboBoxOption = "Option2" }));
_comboOptions.Add(new MyComboBoxOptionsViewModel(new MyComboBoxOptionsModel { ComboBoxOption = "Option3" }));
}
public MyComboBoxOptionsViewModel SelectedItem
{
get { return _selectedItem; }
set
{
_selectedItem = value;
_messages.Add(_selectedItem.ComboBoxOption);
RaisePropertyChangedEvent("SelectedItem");
}
}
public List<MyComboBoxOptionsViewModel> ComboOptions
{
get { return _comboOptions; }
set
{
if (value != _comboOptions)
{
_comboOptions = value;
RaisePropertyChangedEvent("ComboOptions");
}
}
}
public ObservableCollection<MyViewModel> MyObservableCollection
{
get { return _myObservableCollection; }
set
{
if (value != _myObservableCollection)
{
_myObservableCollection = value;
RaisePropertyChangedEvent("MyObservableCollection");
}
}
}
public ObservableCollection<string> Messages
{
get { return _messages; }
set
{
if (value != _messages)
{
_messages = value;
RaisePropertyChangedEvent("Messages");
}
}
}
}
I'm looking at the UI you want and think you basically need a main view model with a collection of item view models.
In that item view model create a command and a selected item property you can bind in your template to the combo box and button. That gives you a strict mvvm binding to a single instance of the combo box value and a command which is executed by the single instance of the button.
Your bindings for combo box items will then need an explicit source as part of the binding so you can hook into one collection of values from the main view model. Or add a collection to your item view model and keep it all nice a clean and together.
As you mention, you're code is very detailed - which is great - but I may have missed some other meaning from it.
Apologies if this is an answer to the wrong question :)

Categories

Resources