Apologies in advance as i'm aware this question has appeared several times. However, i'm struggling to identify where i'm going wrong with my own code. Just looking for a list of checkboxes and names next to them. Currently it compiles ok but the ListBox is empty.
All of the code is within a control called ucDatabases.
XAML:
<ListBox Grid.Row="4" ItemsSource="{Binding Databases}">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding Name}" IsChecked="{Binding IsChecked}" Margin="5 5 0 0"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
C# Code:
public ObservableCollection<CheckBoxDatabase> Databases;
public class CheckBoxDatabase : INotifyPropertyChanged
{
private string name;
private bool isChecked;
public Database Database;
public bool IsChecked
{
get { return isChecked; }
set
{
isChecked = value;
NotifyPropertyChanged("IsChecked");
}
}
public string Name
{
get { return name; }
set
{
name = value;
NotifyPropertyChanged("Name");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(string strPropertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(strPropertyName));
}
}
Helper method to populate some test data:
private void SetTestData()
{
const string dbAlias = "Database ";
Databases = new ObservableCollection<CheckBoxDatabase>();
for (int i = 0; i <= 4; i++)
{
var db = new Database(string.Format(dbAlias + "{0}", i));
var newCBDB = new CheckBoxDatabase {Database = db, IsChecked = false, Name = db.Name};
Databases.Add(newCBDB);
}
}
Advice and a solution would be much appreciated!
public ObservableCollection<CheckBoxDatabase> Databases; is a field.
You should replace it with a Property:
public ObservableCollection<CheckBoxDatabase> Databases {get;set;};
Don't forget INotifyPropertyChanged!
Related
I'm pretty new to programming with WPF and C# and I have a question regarding the possibility to automatically check all the CheckBoxes in a Listbox. I'm developing a plugin for Autodesk Revit and, after having listed all the names of the rooms in a list box, I want to check them all using the button "Check All"
I've read the thread at this page but still, I'm not able to make it work. May someone help me with my code?
Here is what I've done:
XAML:
<ListBox x:Name='roomlist'
SelectionMode='Multiple'>
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked='{Binding IsChecked}'
Content="{Binding}" />
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.InputBindings>
<KeyBinding Command="ApplicationCommands.SelectAll"
Modifiers="Ctrl"
Key="A" />
</ListBox.InputBindings>
<ListBox.CommandBindings>
<CommandBinding Command="ApplicationCommands.SelectAll" />
</ListBox.CommandBindings>
</ListBox>
C#
public partial class RoomsDistance_Form : Window
{
UIDocument _uidoc;
Document _doc;
public RoomsDistance_Form(Document doc, UIDocument uidoc)
{
InitializeComponent();
FilteredElementCollector collector = new FilteredElementCollector(doc)
.WhereElementIsNotElementType()
.OfCategory(BuiltInCategory.OST_Rooms);
List<String> myRooms = new List<String>();
foreach (var c in collector)
{
myRooms.Add(c.Name);
}
myRooms.Sort();
roomlist.ItemsSource = myRooms;
}
private void checkAllBtn_Click(object sender, RoutedEventArgs e)
{
foreach (CheckBox item in roomlist.Items.OfType<CheckBox>())
{
item.IsChecked = true;
}
}
public class Authority : INotifyPropertyChanged
{
private bool isChecked;
public bool IsChecked
{
get { return isChecked; }
set
{
isChecked = value;
NotifyPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
Thank you very much for your help!
In the thread you are linking to, they are setting the "IsChecked" on the data object (Authority), not the CheckBox control itself.
foreach (var a in authorityList)
{
a.IsChecked = true;
}
You have a binding to IsChecked that will update the Checkbox control when NotifyPropertyChanged() is called.
After having lost my mind in the effort i solved my problem by avoiding the Listbox.. I simply added single CheckBoxes in the StackPanel.
XAML:
<ScrollViewer Margin='10,45,10,100'
BorderThickness='1'>
<StackPanel x:Name='stack'
Grid.Column='0'></StackPanel>
</ScrollViewer>
C#:
foreach (var x in myRooms)
{
CheckBox chk = new CheckBox();
chk.Content = x;
stack.Children.Add(chk);
}
Not what i was looking for but now it works and that's the point.
Thank you for your help!
I usually use CheckBoxList in the following way:
In xaml:
<ListBox ItemsSource="{Binding ListBoxItems, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"> //+some dimensional properties
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding Name}" IsChecked="{Binding IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
In xaml.cs:
public partial class MyWindow : Window
{
public ViewModel ViewModel {get; set; }
public MyWindow(ViewModel viewModel)
{
//keep all the mess in ViewModel, this way your xaml.cs will not end up with 1k lines
ViewModel = viewModel;
DataContext = ViewModel;
InitializeComponent();
}
void BtnClick_SelectAll(object sender, RoutedEventArgs e)
{
ViewModel.CheckAll();
}
}
ViewModel preparation:
public class ViewModel
{
public List<ListBoxItem> ListBoxItems { get; set; }
//InitializeViewModel()...
//UpdateViewModel()...
//other things....
public void CheckAll()
{
foreach (var item in ListBoxItems)
{
item.IsSelected = true;
}
}
public class ListBoxItem : INotifyPropertyChanged
{
public string Name { get; set; }
private bool _isSelected;
public bool IsSelected
{
get { return _isSelected; }
set
{
if (_isSelected != value)
{
_isSelected = value;
OnPropertyChanged(nameof(IsSelected));
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
I have a WorkspaceViewModel that handles addition and deletion of tab items dynamically through an ObservableCollection. Each time a tab is connected to a PayslipModel, all bindings work fine but one problem I am having is that;
I have a save button in the UserControl who's DataContext is set to WorkspaceViewModel and I would like to save whatever info is being displayed in the selected tab. Now, each time a tab is added, a new instance of PayslipModel is created, which is exactly what I want because I don't want bindings to be shared for all tabs. However, I am unable to save what is being displayed since PayslipModel has multiple instances, therefore nothing is returned (temporarily using MessageBox to test if info is being retrieved) when I hit save.
I created a diagram to better explain my situation:
Is it possible to access the current instance when a tab is selected or cycle through all instances and do something like batch saving?
This is a working example which shows one of the possiblities:
View
<TabControl DataContext="{Binding}" ItemsSource="{Binding Models}" >
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" >
</TextBlock>
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate>
<DockPanel>
<Button DockPanel.Dock="Top" Content="Click Me" Command="{Binding DataContext.PCommand,
RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=TabControl}}"
CommandParameter="{Binding Desc}"/>
<TextBlock Text="{Binding Desc}" >
</TextBlock>
</DockPanel>
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
Model View
public class ModelView
{
public ModelView()
{
_models = new ObservableCollection<Model>();
_pCommand = new Command(DoParameterisedCommand);
}
ObservableCollection<Model> _models;
public ObservableCollection<Model> Models { get { return _models; } }
private void DoParameterisedCommand(object parameter)
{
MessageBox.Show("Parameterised Command; Parameter is '" +
parameter.ToString() + "'.");
}
Command _pCommand;
public Command PCommand
{
get { return _pCommand; }
}
}
Model
public class Model : INotifyPropertyChanged
{
string _desc;
public string Desc { get { return _desc; } set { _desc = value; RaisePropertyChanged("Desc"); } }
string _name;
public string Name { get { return _name; } set { _name = value; RaisePropertyChanged("Name"); } }
public event PropertyChangedEventHandler PropertyChanged;
void RaisePropertyChanged(string propname)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propname));
}
}
Command
public class Command : ICommand
{
public Command(Action<object> parameterizedAction, bool canExecute = true)
{
_parameterizedAction = parameterizedAction;
_canExecute = canExecute;
}
Action<object> _parameterizedAction = null;
bool _canExecute = false;
public bool CanExecute
{
get { return _canExecute; }
set
{
if (_canExecute != value)
{
_canExecute = value;
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}
}
}
public event EventHandler CanExecuteChanged;
bool ICommand.CanExecute(object parameter)
{
return _canExecute;
}
void ICommand.Execute(object parameter)
{
this.DoExecute(parameter);
}
public virtual void DoExecute(object param)
{ if (_parameterizedAction != null)
_parameterizedAction(param);
else
throw new Exception();
}
}
Use this to initialize:
public MainWindow()
{
InitializeComponent();
ModelView mv = new ModelView();
mv.Models.Add(new Model() { Name = "a", Desc = "aaa" });
mv.Models.Add(new Model() { Name = "b" , Desc = "bbb"});
mv.Models.Add(new Model() { Name = "c", Desc = "cccc" });
this.DataContext = mv;
}
I have two different objects that are pointing at each other. The first object represents a division in a company. That object has two collection: Employees, which is all the employees working in the division and Project, which is all the special projects that are in progress within that division. So the first object looks like this:
public class Division : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = delegate { };
ObservableCollection<Employee> _employees;
ObservableCollection<Project> _projects;
public Division()
{
Employees = new ObservableCollection<Employee>();
Projects = new ObservableCollection<Project>();
}
public ObservableCollection<Employee> Employees
{
get { return _employees; }
set
{
if (_employees != value)
{
_employees = value;
PropertyChanged(this, new PropertyChangedEventArgs("Employees"));
}
}
}
public ObservableCollection<Project> Projects
{
get { return _projects; }
set
{
if (_projects != value)
{
_projects = value;
PropertyChanged(this, new PropertyChangedEventArgs("Projects"));
}
}
}
public void AddNewProject()
{
this.Projects.Add(new Project(this));
}
}
Notice that when adding a new project to the division, I pass a reference to the division into that project, which looks like this:
public class Project : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = delegate { };
string _projectName;
DateTime _deadline = DateTime.Now;
Division _division;
ObservableCollection<Employee> _members;
public Project()
{
Members = new ObservableCollection<Employee>();
}
public Project(Division div)
{
Members = new ObservableCollection<Employee>();
Division = div;
}
public string ProjectName
{
get { return _projectName; }
set
{
if (_projectName != value)
{
_projectName = value;
PropertyChanged(this, new PropertyChangedEventArgs("ProjectName"));
}
}
}
public DateTime Deadline
{
get { return _deadline; }
set
{
if (_deadline != value)
{
_deadline = value;
PropertyChanged(this, new PropertyChangedEventArgs("Deadline"));
}
}
}
public Division Division
{
get { return _division; }
set
{
if (_division != value)
{
if (_division != null)
{
_division.Employees.CollectionChanged -= members_CollectionChanged;
}
_division = value;
if (_division != null)
{
_division.Employees.CollectionChanged += members_CollectionChanged;
}
PropertyChanged(this, new PropertyChangedEventArgs("Division"));
}
}
}
public ObservableCollection<Employee> Members
{
get { return _members; }
set
{
if (_members != value)
{
if (_members != null)
{
_members.CollectionChanged -= members_CollectionChanged;
}
_members = value;
if (_members != null)
{
_members.CollectionChanged += members_CollectionChanged;
}
PropertyChanged(this, new PropertyChangedEventArgs("Members"));
}
}
}
public ObservableCollection<Employee> AvailableEmployees
{
get
{
if (Division != null){
IEnumerable<Employee> availables =
from s in Division.Employees
where !Members.Contains(s)
select s;
return new ObservableCollection<Employee>(availables);
}
return new ObservableCollection<Employee>();
}
}
void members_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
PropertyChanged(this, new PropertyChangedEventArgs("AvailableEmployees"));
}
}
The reason I'm doing it like this is, that the project could have any type of team working on it, but only from within the division. So, when building a dashboard for the division, the manager could select any of the employees to that project but without putting in an employee that is already assigned to it. So, the AvailableEmployees property in the project object always keeps track of who is not already assigned to that project.
The problem I'm having is how to translate this into a UI. The experiment I've done so far looks like this:
<UserControl x:Class="Test.Views.TestView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
xmlns:local="clr-namespace:Test.Views"
d:DesignHeight="300" d:DesignWidth="300">
<StackPanel>
<ListBox ItemsSource="{Binding Div.Projects}">
<ListBox.ItemTemplate>
<DataTemplate>
<Border Background="Transparent"
BorderThickness="0, 0, 0, 2"
BorderBrush="Black"
Margin="0, 0, 0, 5"
Padding="0, 0, 0, 5">
<StackPanel>
<TextBox Text="{Binding ProjectName}"/>
<ListBox ItemsSource="{Binding Members}">
<ListBox.ItemTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=local:TestView}, Path=DataContext.AvailableEmployees}"
DisplayMemberPath="FirstName"
Text="{Binding FirstName}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button Content="Add Employee to Project"
Command="{Binding RelativeSource={RelativeSource AncestorType=local:TestView}, Path=DataContext.AddEmployeeToProject}"
CommandParameter="{Binding}"/>
</StackPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button Content="Add New Project"
Command="{Binding AddNewProject}" />
</StackPanel>
The view model associated with this view is as follows:
public class TestViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = delegate { };
private Division _div;
public TestViewModel(Division div)
{
Div = div;
AddNewProject = new DelegateCommand(OnAddNewProject);
AddEmployeeToProject = new DelegateCommand<Project>(OnAddEmployeeToProject);
}
public DelegateCommand AddNewProject { get; set; }
public DelegateCommand<Project> AddEmployeeToProject { get; set; }
public Division Div
{
get { return _div; }
set
{
if (_div != value)
{
_div = value;
PropertyChanged(this, new PropertyChangedEventArgs("Div"));
}
}
}
private void OnAddNewProject()
{
Div.AddNewProject();
}
private void OnAddEmployeeToProject(Project proj)
{
var availables = proj.AvailableEmployees;
if (availables.Count > 0)
{
proj.Members.Add(availables[0]);
}
}
}
However, I cannot get the combobox for each employee in each project to work. It seems like the selected item/value is bound to the itemssource, and each time the combobox turns out blank. I've tried to do this also with SelectedValue and SelectedItem properties for the combobox, but none worked.
How do I get these two separated. Is there anything else I'm missing here?
OK. After so many experiments the best solution I came up with was to create my own user control that is composed of both a button and a combobox that imitate the behavior I was expecting of the combobox on it own.
First, I had a really stupid mistake in the model where both lists of members Project and Division contain the same instances of Employee, which makes the AvailableEmployees property buggy. What I really needed to do is to create a list of copies of employees in the Project instead of just references.
In any case, I created a new user control and called it DynamicSourceComboBox. The XAML of this control looks like this:
<Grid>
<Button x:Name="selected"
Content="{Binding RelativeSource={RelativeSource AncestorType=local:DynamicSourceComboBox}, Path=SelectedValue}"
Click="selected_Click"/>
<ComboBox x:Name="selections"
ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=local:DynamicSourceComboBox}, Path=ItemsSource}"
DisplayMemberPath="{Binding RelativeSource={RelativeSource AncestorType=local:DynamicSourceComboBox}, Path=DisplayMemberPath}"
Visibility="Collapsed"
SelectionChanged="selections_SelectionChanged"
MouseLeave="selections_MouseLeave"/>
</Grid>
I have here a few bindings from the button and the combobox to properties in my user control. These are actually dependency properties. The code-behind of my user control looks like this:
public partial class DynamicSourceComboBox : UserControl
{
public DynamicSourceComboBox()
{
InitializeComponent();
}
public object SelectedValue
{
get { return (object)GetValue(SelectedValueProperty); }
set { SetValue(SelectedValueProperty, value); }
}
public static readonly DependencyProperty SelectedValueProperty =
DependencyProperty.Register("SelectedValue", typeof(object), typeof(DynamicSourceComboBox), new PropertyMetadata(null));
public IEnumerable ItemsSource
{
get { return (IEnumerable)GetValue(ItemsSourceProperty); }
set { SetValue(ItemsSourceProperty, value); }
}
public static readonly DependencyProperty ItemsSourceProperty =
ComboBox.ItemsSourceProperty.AddOwner(typeof(DynamicSourceComboBox));
public string DisplayMemberPath
{
get { return (string)GetValue(DisplayMemberPathProperty); }
set { SetValue(DisplayMemberPathProperty, value); }
}
public static readonly DependencyProperty DisplayMemberPathProperty =
ComboBox.DisplayMemberPathProperty.AddOwner(typeof(DynamicSourceComboBox));
private void selected_Click(object sender, RoutedEventArgs e)
{
selected.Visibility = Visibility.Hidden;
selections.Visibility = Visibility.Visible;
selections.IsDropDownOpen = true;
}
private void selections_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
selections.Visibility = Visibility.Collapsed;
selected.Visibility = Visibility.Visible;
selections.IsDropDownOpen = false;
if (e.AddedItems.Count == 1)
{
var item = e.AddedItems[0];
Type itemType = item.GetType();
var itemTypeProps = itemType.GetProperties();
var realValue = (from prop in itemTypeProps
where prop.Name == DisplayMemberPath
select prop.GetValue(selections.SelectedValue)).First();
SelectedValue = realValue;
}
}
private void selections_MouseLeave(object sender, MouseEventArgs e)
{
selections.Visibility = Visibility.Collapsed;
selected.Visibility = Visibility.Visible;
selections.IsDropDownOpen = false;
}
}
These dependency properties imitate the properties with similar names in ComboBox but they are hooked up to the internal combobox and the button in a way that makes them behave together as a single complex combobox.
The Click event in the button hides it and present the combobox to make the effect of just a box that is opening. Then I have a SelectionChanged event in the combobox firing to update all the needed information and a MouseLeave event just in case the user doesn't make any real selection change.
When I need to use the new user control, I set it up like this:
<local:DynamicSourceComboBox ItemsSource="{Binding RelativeSource={RelativeSource AncestorLevel=1, AncestorType=ListBox}, Path=DataContext.AvailableEmployees}"
DisplayMemberPath="FirstName"
SelectedValue="{Binding FirstName, Mode=TwoWay}"/>
Of course, for all of it to work, I have to make a lot of hookups with PropertyChanged events in the models, so the Projects instance will know to raise a PropertyChanged event for AvailableEmployees any time a change is made, but this is not really the concern of this user control itself.
This is a pretty clunky solution, with a lot of extra code that is a bit hard to follow, but it's really the best (actually only) solution I could have come up with to the problem I had.
I have a Listbox
<ListBox Name="lstbox">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBox Name="text" Background="White" Foreground="Black" Width="400"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Here is c# code
List<string> lst = new List<string>();
// Constructor
public MainPage()
{
for (int i = 0; i < 100; i++)
{
lst.Add("a"+i.ToString());
}
lstbox.ItemsSource = lst;
}
I want that user input values in textboxes inside the list box. And the values are display in the textboxes permanently. But When I'm entering a value in a textbox, it is showing the value in other textboxes also. Also when I'm scrolling the list Value entered in text box is lost. Please Help
I can replicate the same weird behavior when i try it too. I suggest you try turning your list into some sort of model that implements the INotifyPropertyChanged interface. It seems like you want changes made from the UI (textboxes) reflected ion the collection as well, hence this is a better/cleaner approach IMHO.
Xaml
<ListBox Name="lstbox">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding Name, Mode=TwoWay}" Background="White" Foreground="Black" Width="400"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Code behind
public partial class MainPage : PhoneApplicationPage
{
private readonly ObservableCollection<Customer> customers = new ObservableCollection<Customer>();
// Constructor
public MainPage()
{
InitializeComponent();
for (int i = 0; i < 100; i++)
{
customers.Add(new Customer { Name =" Customer " + i });
}
lstbox.ItemsSource = customers;
}
}
public class Customer : INotifyPropertyChanged
{
private string name;
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
public string Name
{
get { return this.name; }
set
{
if (value != this.name)
{
this.name = value;
OnPropertyChanged();
}
}
}
}
I am working on a combobox for more than 2 days but did not find the solution.
In one of my question a user named JnJnBoo tried to answer my question and I got some knowledge and code from there.
I am trying to display some data in a combobox in multiple columns using MVVM pattern.
I am using entity framework and SQL Server database.
Here is the code :
namespace ERP_Lite_Trial.ViewModels
{
public class GroupsViewModel : INotifyPropertyChanged
{
public GroupsViewModel()
{
using (DBEntities db = new DBEntities())
{
GroupsAndCorrespondingEffects = (from g in db.Groups
select new GroupAndCorrespondingEffect
{
GroupName = g.Name,
CorrespondingEffect = g.Type_Effect.Name
}
).ToList();
EffectName = (from e in db.Type_Effect
select e.Name).ToList();
}
}
private List<GroupAndCorrespondingEffect> _groupsAndCorrespondingEffects;
public List<GroupAndCorrespondingEffect> GroupsAndCorrespondingEffects
{
get
{
return _groupsAndCorrespondingEffects;
}
set
{
_groupsAndCorrespondingEffects = value;
OnPropertyChanged("GroupsAndCorrespondingEffects");
}
}
private string _selectedGroup;
public string SelectedGroup
{
get
{
return _selectedGroup;
}
set
{
_selectedGroup = value;
OnPropertyChanged("SelectedGroup");
}
}
private List<string> _effectName;
public List<string> EffectName
{
get
{
return _effectName;
}
set
{
_effectName = value;
OnPropertyChanged("EffectName");
}
}
public void OnPropertyChanged(string PropertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
public class GroupAndCorrespondingEffect
{
public string GroupName;
public string CorrespondingEffect;
}
}
And the XAML :
<ComboBox x:Name="cbUnder" ItemsSource="{Binding Path=GroupsAndCorrespondingEffects}"
IsEditable="True" SelectedItem="{Binding Path=SelectedGroup, Mode=TwoWay}"
TextSearch.TextPath="GroupName" Grid.Column="1" Grid.ColumnSpan="4" Grid.Row="3">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=GroupName}"/>
<TextBlock Text="{Binding Path=CorrespondingEffects}"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
I tried many things but always unsuccessful.
My Combobox is not displaying any data in its items but when I select any Item in the combobox then I get some data in the selectedGroup property. The data is namespace.classname
So I think I need to override the Tostring Method of GroupAndCorrespondingEffect class. But It has got two properties. In which format the databinding in XAML expects the data that is not known to me. So, how to override the tostring method? Or might be I am making some sort of mistake in my code?
Your GroupAndCorrespondingEffect should look like the following
public class GroupAndCorrespondingEffect
{
public string GroupName;
{
get;
set;
}
public string CorrespondingEffect;
{
get;
set;
}
}
And in you XAML
<TextBlock Text="{Binding Path=CorrespondingEffects}"/>
The property name is wrong it contains additional s
so it should be
<TextBlock Text="{Binding Path=CorrespondingEffect}"/>
public class GroupAndCorrespondingEffect
{
public string GroupName;
public string CorrespondingEffect;
}
Make the public variables GroupName and CorrespondingEffect as properties
And in your View model change the type of the property SelectedGroup like below
private GroupAndCorrespondingEffect _selectedGroup;
public GroupAndCorrespondingEffect SelectedGroup
{
get
{
return _selectedGroup;
}
set
{
_selectedGroup = value;
OnPropertyChanged("SelectedGroup");
}
}