Assign combobox value in wpf - wpf

Please let me know how to assign value to combobox with following code, as assign the Display text
`<ComboBox x:Name="ComboBox" HorizontalAlignment="Left" Margin="256,41,0,-6"
VerticalAlignment="Top" Width="108" Height="26" FontSize="13" >
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>`

You can simply use DisplayMemberPath property to set the name of the column of your DataTable which will be displayed.
Code behind:
ComboBox.ItemsSource = dt.AsDataView();
XAML:
<ComboBox x:Name="ComboBox" DisplayMemberPath="Name" HorizontalAlignment="Left" Margin="256,41,0,-6"
VerticalAlignment="Top" Width="108" Height="26" FontSize="13">
</ComboBox>

You have to create a list of strings called Name in your viewModel that implements INotifyPropertyChanged

XAML:
<ComboBox x:Name="ComboBox" ItemsSource="{Binding myListofItems}" HorizontalAlignment="Left" Margin="256,41,0,-6" VerticalAlignment="Top" Width="108" Height="26" FontSize="13" />
C#:
public partial class MainWindow : Window, INotifyPropertyChanged
{
private List<string> _myListOfItems = new List<string> ();
public List<string> myListOfItems
{
get { return (_myListOfItems); }
set
{
_myListOfItems = value;
OnPropertyChanged ("myListOfItems");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null) {
handler (this, new PropertyChangedEventArgs (propertyName));
}
}
public MainWindow()
{
InitializeComponent ();
this.DataContext = this;
// Start Populating your List here
// Example:
for (int i = 0; i < 10; i++) {
myListOfItems.Add (i.ToString ());
}
}
}

<ComboBox x:Name="cmbSubLocation"
DisplayMemberPath="SubLocationName" SelectedValuePath="Id"
VerticalAlignment="Top" Width="108" Height="26" FontSize="13" >
</ComboBox>

Related

How to set bind a text box to a class not in the data context class

I have this dock panel which I'm trying to set up bindings for.
The problem is that my DataContext for my XAML is set to the MainWindow class but my class that I want to bind to (autoCam) is separate from that class. I have an instance of autoCam being used in the MainWindow class, called "myCam", but I've gotten confused about how to get these bindings to work.
This is the code I'm using in my dock panel:
<DockPanel x:Name="BottomDock" Visibility="Collapsed" Grid.Column="2" Grid.Row="2" Grid.ColumnSpan="2" DockPanel.Dock="Bottom" Margin="0">
<Button x:Name="Rewind" Click="Rewind_Click" HorizontalAlignment="Left" Width="23" RenderTransformOrigin="0.5,0.5" Grid.Row="1"/>
<Button x:Name="Play" Content=">" Click="Play_Click" HorizontalAlignment="Left" Width="17" RenderTransformOrigin="0.5,0.5" Grid.Row="1"/>
<Button x:Name="Pause" Content="||" Click ="Pause_Click" HorizontalAlignment="Left" VerticalAlignment="Top" Width="16" Height="22" RenderTransformOrigin="0.5,0.5" Grid.Row="1"/>
<Button x:Name="FastForward" Content=">>" Click="FastForward_Click" HorizontalAlignment="Left" Width="23" RenderTransformOrigin="0.5,0.5" Grid.Row="1"/>
<TextBlock Background="Black" TextAlignment="Center" Foreground="AliceBlue" HorizontalAlignment="Left" Width="95" Text="Camera Position"/>
<TextBox Background="Black" TextAlignment="Center" Foreground="AliceBlue" HorizontalAlignment="Left" Width="40" Name="cpx" Text="{Binding Path=myCam.cameraPositionX, UpdateSourceTrigger=PropertyChanged}"/>
<TextBox Background="Black" TextAlignment="Center" Foreground="AliceBlue" HorizontalAlignment="Left" Width="40" Name="cpy" Text="{Binding Path=myCam.cameraPositionY, UpdateSourceTrigger=PropertyChanged}"/>
<TextBox Background="Black" TextAlignment="Center" Foreground="AliceBlue" HorizontalAlignment="Left" Width="40" Name="cpz" Text="{Binding Path=myCam.cameraPositionZ, UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock Background="Black" TextAlignment="Center" Foreground="AliceBlue" HorizontalAlignment="Left" Width="95" Text="Look Direction"/>
<TextBox Background="Black" TextAlignment="Center" Foreground="AliceBlue" HorizontalAlignment="Left" Width="40" Name="ldx" Text="{Binding Path=myCam.lookDirectionX, UpdateSourceTrigger=PropertyChanged}"/>
<TextBox Background="Black" TextAlignment="Center" Foreground="AliceBlue" HorizontalAlignment="Left" Width="40" Name="ldy" Text="{Binding Path=myCam.lookDirectionY, UpdateSourceTrigger=PropertyChanged}"/>
<TextBox Background="Black" TextAlignment="Center" Foreground="AliceBlue" HorizontalAlignment="Left" Width="40" Name="ldz" Text="{Binding Path=myCam.lookDirectionZ, UpdateSourceTrigger=PropertyChanged}"/>
</DockPanel>
At first I thought I could just write DataContext=autoCam as a property of the dock panel itself, or for each individual textbox and then just say {binding cameraPositionX} or something, but that didn't do anything.
Then i thought I could just say {Binding myCam.cameraPositionX} since myCam is a member of the MainWindow class. But that didn't work either.
In a futile attempt, I tried to sort of combine both of my guesses and add DataContext=autoCam to properties of all of the text boxes but I never thought that would actually work.
I also tried to write the following after the datacontext=this; line in the mainwindow constructor. I tried this in case the problem was that the xaml would set the datacontext properly as i wanted it, but then the datacontext for the entire ui would be reapplied to the mainwindow when the constructor was run.
public MainWindow()
{
InitializeComponent();
Interval = new TimeSpan(0, 0, 0, 0, 10);
Rewind.Content = "<<";
runType = 2;
timerRate(runType);
Loaded += new RoutedEventHandler(MainWindow_Loaded);
DataContext = this;
cpx.DataContext = myCam;
cpy.DataContext = myCam;
cpx.DataContext = myCam;
ldx.DataContext = myCam;
ldy.DataContext = myCam;
ldz.DataContext = myCam;
//view1.IsHeadLightEnabled = true;
}
I thought that maybe I could put this in the Window.Resources XAML:
<Window.Resources>
<ObjectDataProvider x:Key="Camera" ObjectType="{x:Type local:autoCam}" MethodName="getCamDetails"/>
</Window.Resources>
but i wrote my method getCamDetails in my autoCam class as follows, and it's giving me a null reference exception every time i try to set CamDetails[0] to cameraPositionX.
public class autoCam : INotifyPropertyChanged
{
MainWindow mW;
public static double[] CamDetails;
public static double[] getCamDetails()
{
return CamDetails;
}
public Point3D cameraPosition
{
get { return mC.Position; }
set
{
mC.Position = value;
cameraPositionX = Convert.ToDouble(cameraPosition.X);
cameraPositionY = Convert.ToDouble(cameraPosition.Y);
cameraPositionZ = Convert.ToDouble(cameraPosition.Z);
lookDirection = mC.LookDirection;
lookDirectionX = Convert.ToDouble(lookDirection.X);
lookDirectionY = Convert.ToDouble(lookDirection.Y);
lookDirectionZ = Convert.ToDouble(lookDirection.Z);
onPropertyChanged("cameraPosition");
}
}
public double cameraPositionX
{
get { return Convert.ToDouble(cameraPosition.X); }
set { onPropertyChanged("cameraPositionX"); CamDetails[0] = cameraPositionX; }
}
public double cameraPositionY
{
get { return Convert.ToDouble(cameraPosition.Y); }
set { onPropertyChanged("cameraPositionY"); CamDetails[1] = cameraPositionY; }
}
public double cameraPositionZ
{
get { return Convert.ToDouble(cameraPosition.Z); }
set { onPropertyChanged("cameraPositionZ"); CamDetails[2] = cameraPositionZ; }
}
public Vector3D lookDirection
{
get { return mC.LookDirection; }
set {
mC.LookDirection = value;
lookDirectionX = Convert.ToDouble(lookDirection.X);
lookDirectionY = Convert.ToDouble(lookDirection.Y);
lookDirectionZ = Convert.ToDouble(lookDirection.Z);
onPropertyChanged("lookDirection");
}
}
public double lookDirectionX
{
get { return Convert.ToDouble(lookDirection.X);}
set { onPropertyChanged("lookDirectionX"); CamDetails[3] = lookDirectionX; }
}
public double lookDirectionY
{
get { return Convert.ToDouble(lookDirection.Y); }
set { onPropertyChanged("lookDirectionY"); CamDetails[4] = lookDirectionY; }
}
public double lookDirectionZ
{
get { return Convert.ToDouble(lookDirection.Z); }
set { onPropertyChanged("lookDirectionZ"); CamDetails[5] = lookDirectionZ; }
I would really appreciate a solution, but a break down of why these aren't working for me is essentially going to help me a lot more in the long run.
Thank you for your time and help everyone.
It would have been better to share the MainWindow class too but it sounds like putting a property in your MainWindow class to expose the myCam instance and binding directly to that property should work.
public partial class MainWindow : Window
{
private AutoCam autoCam;
public AutoCam AutoCam
{
get { return autoCam; }
set { autoCam = value; }
}
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
this.autoCam = new AutoCam();
}
}
public class AutoCam
{
private string someText;
public string SomeText
{
get { return someText; }
set { someText = value; }
}
public AutoCam()
{
this.SomeText = "Some Text";
}
}
And the binding will be like this.
<Label Content="{Binding AutoCam.SomeText}">

WPF displaying object properties from Observable Collection MVVM

I am trying to display the properties from an object which is contained in an observable list but it is just not working.
I was hoping someone could point me in the right direction.
Here is my XAMl
<Window x:Name="MainViewWindow" x:Class="WpfApplication1.View.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local ="clr-namespace:WpfApplication1.ViewModel"
Title="MainView" Height="413.514" Width="607.095">
<Window.DataContext>
<local:MainViewModel />
</Window.DataContext>
<Grid>
<Label Content="Text:" HorizontalAlignment="Left" Margin="55,135,0,0" VerticalAlignment="Top"/>
<Label Content="{Binding Name}" HorizontalAlignment="Left" Margin="98,135,0,0" VerticalAlignment="Top"/>
<Button Content="Button" HorizontalAlignment="Left" Margin="61,108,0,0" VerticalAlignment="Top" Width="75" Command="{Binding UpdateNameCommand}"/>
<Label Content="ActivateButton" HorizontalAlignment="Left" Margin="52,82,0,0" VerticalAlignment="Top"/>
<CheckBox Content="CheckBox" HorizontalAlignment="Left" Margin="173,87,0,0" VerticalAlignment="Top" IsChecked="{Binding ButtonActive}" />
<Label Content="CustomerName" HorizontalAlignment="Left" Margin="55,166,0,0" VerticalAlignment="Top"/>
<StackPanel HorizontalAlignment="Left" Height="100" Margin="173,166,0,0" VerticalAlignment="Top" Width="100"/>
<ItemsControl x:Name="lstPeople" Background="AliceBlue" Width="130" Margin="273,29,196,35" ItemsSource="{Binding CustomerList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
My CustomerList is a property located in the MainViewModel:
ObservableCollection<Customer> _CustomerList;
ObservableCollection<Customer> CustomerList
{
get { return _CustomerList; }
set
{
if (_CustomerList != value)
{
_CustomerList = value;
PropertyChanged(this, new PropertyChangedEventArgs("CustomerList"));
}
}
}
My Customer class only contains one property: Name
public class Customer : INotifyPropertyChanged
{
private string _Name;
public string Name
{
get { return _Name; }
set
{
if (_Name != value)
{
_Name = value;
PropertyChanged(this, new PropertyChangedEventArgs("Name"));
}
}
}
public event PropertyChangedEventHandler PropertyChanged = delegate { };
}
I have created an instance of the CustomerList in the MainViewModel constructor but i cannot see any of my customers showing up in the application:
public MainViewModel()
{
ButtonActive = true;
CustomerList = new ObservableCollection<Customer>() { new Customer() { Name = "NewCust33" } };
CustomerList.Add(new Customer() { Name = "NewCust" });
}
It looks like the property you're binding to is private?
You can only bind to public properties.
public ObservableCollection<Customer> CustomerList

WPF : Passing Custom data to between Custom Control and parent

I am total newbie to WPF. I am creating my custom user control which will display the employee data structure which is as follows I have implemented INotifyPropertyChanged also:
Here's code snippet
public class Employee : INotifyPropertyChanged
{
private int id;
private string name;
private double salary;
private EmployeeDesignation designation;
public int ID
{
get
{
return id;
}
set
{
id = value;
OnPropertyChanged(new PropertyChangedEventArgs("ID"));
//PropertyChanged(ID, new PropertyChangedEventArgs("ID"));
}
}
...
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (PropertyChanged != null)
{
PropertyChanged(this, e);
}
}
}
}
And user control code is as follows :
<UserControl x:Class="Assignment5.EmployeeUserControl"
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://scenter code herehemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d" DataContext="{Binding RelativeSource={RelativeSource Self}, Path=.}"
d:DesignHeight="196" d:DesignWidth="300">
<Grid Height="182">
<Label Content="Name" Height="28" HorizontalAlignment="Left" Margin="26,57,0,0" Name="label1" VerticalAlignment="Top" Width="76" />
<Label Content="Salary" Height="28" HorizontalAlignment="Left" Margin="26,91,0,0" Name="label2" VerticalAlignment="Top" />
<Label Content="ID" Height="28" HorizontalAlignment="Left" Margin="26,23,0,0" Name="label3" VerticalAlignment="Top" />
<Label Content="Designation" Height="28" HorizontalAlignment="Left" Margin="26,125,0,0" Name="label4" VerticalAlignment="Top" />
<TextBox Text="{Binding ElementName=Employee, Path=ID}" Height="23" HorizontalAlignment="Left" Margin="134,28,0,0" Name="IdTextBox" VerticalAlignment="Top" Width="120" />
<TextBox Text="{Binding ElementName=Employee, Path=Name}" Height="23" HorizontalAlignment="Left" Margin="134,59,0,0" Name="NameTextBox" VerticalAlignment="Top" Width="120" />
<TextBox Text="{Binding ElementName=Employee, Path=Salary}" Height="23" HorizontalAlignment="Left" Margin="134,91,0,0" Name="SalaryTextBox" VerticalAlignment="Top" Width="120" LostFocus="SalaryTextBoxLostFocus" />
<TextBox Text="{Binding ElementName=Employee, Path=designation}" Height="23" HorizontalAlignment="Left" Margin="134,125,0,0" Name="DesignationTextBox" VerticalAlignment="Top" Width="120" />
</Grid>
</UserControl>
Here's code behind file
namespace Assignment5
{
public partial class EmployeeUserControl : UserControl, INotifyPropertyChanged
{
public static readonly DependencyProperty EmpDependancyProperty =
DependencyProperty.Register("Employee", typeof(Employee), typeof(EmployeeUserControl)
, new PropertyMetadata(
new PropertyChangedCallback(
EmployeeUserControl.EmployeeDataChanged)));
public Employee Employee
{
get
{
return (Employee)GetValue(EmpDependancyProperty);
}
set
{
SetValue(EmpDependancyProperty, value);
}
}
public EmployeeUserControl()
{
InitializeComponent();
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
private void SalaryTextBoxLostFocus(object sender, RoutedEventArgs e)
{
MessageBox.Show(Employee.Name);
}
private static void EmployeeDataChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
EmployeeUserControl userControl = d as EmployeeUserControl;
userControl.OnPropertyChanged("Employee");
}
}
}
Here's my parent control...
<Window x:Class="Assignment5.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" xmlns:my="clr-namespace:Assignment5"
DataContext="{Binding RelativeSource={RelativeSource Self}, Path=.}">
<Grid>
<my:EmployeeUserControl Employee="{Binding Path=emp, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay, NotifyOnSourceUpdated=True, NotifyOnTargetUpdated=True}" HorizontalAlignment="Left" Margin="130,56,0,0" x:Name="employeeUserControl1" VerticalAlignment="Top" Width="285" />
</Grid>
</Window>
and a code behind :
namespace Assignment5
{
public partial class MainWindow : Window
{
public static readonly DependencyProperty EmpDependancyProperty =
DependencyProperty.Register("Employee", typeof(Employee), typeof(EmployeeUserControl)
, new PropertyMetadata(
new PropertyChangedCallback(
EmployeeUserControl.EmployeeDataChanged)));
public Employee Employee
{
get
{
return (Employee)GetValue(EmpDependancyProperty);
}
set
{
SetValue(EmpDependancyProperty, value);
}
}
public MainWindow()
{
emp = new Employee(203,"AAA",23232);
InitializeComponent();
}
}
}
When I run this code. I came to know that Employee object in parent control is getting initialized but in the user control it is not getting initialized. What I am doing wrong here?
Two issues
In your UserControl change the Bindings to
<TextBox Text="{Binding Path=Employee.ID}" Height="23" HorizontalAlignment="Left" Margin="134,28,0,0" Name="IdTextBox" VerticalAlignment="Top" Width="120" />
<TextBox Text="{Binding Employee.Name}" Height="23" HorizontalAlignment="Left" Margin="134,59,0,0" Name="NameTextBox" VerticalAlignment="Top" Width="120" />
<TextBox Text="{Binding Employee.Salary}" Height="23" HorizontalAlignment="Left" Margin="134,91,0,0" Name="SalaryTextBox" VerticalAlignment="Top" Width="120" LostFocus="SalaryTextBoxLostFocus" />
<TextBox Text="{Binding Employee.designation}" Height="23" HorizontalAlignment="Left" Margin="134,125,0,0" Name="DesignationTextBox" VerticalAlignment="Top" Width="120" />
In your Window:
<my:EmployeeUserControl Employee="{Binding Employee, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay, NotifyOnSourceUpdated=True, NotifyOnTargetUpdated=True}" HorizontalAlignment="Left" Margin="130,56,0,0" x:Name="employeeUserControl1" VerticalAlignment="Top" Width="285" />
In your constructor emp = new Employee(203,"AAA",23232); does not make any sense. Instead do this.Employee = new Employee(203,"AAA",23232);

ListBox binding with ViewModel in WPF

I am new to the WPF and trying to build a sample application using the MVVM framework. My application has a xaml file which has some textboxes for inputing customer info, combo box for display of states and a save button. All the databinding is done through ViewModel(CustomerViewMode) which has a reference to the Model(Customer), containing the required fields and their
Getter, setters. The viewModel has a CustomerList property.
On clicking the save button, I want to display the FirstName and LastName properties of Customer in a ListBox. This is where the problem is. I debugged the code,
(Click event of button in the code behind), I can see that the CustomerList has the first Customer object with all its details, but its not getting displayed in the listbox.
My code is:
Customer(Model);
enter code here
namespace SampleMVVM.Models
{
class Customer : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private String _firstName;
private String _lastName;
private Address _customerAddress;
public String FirstName
{
get { return _firstName; }
set
{
if (value != _firstName)
{
_firstName = value;
RaisePropertyChanged("FirstName");
}
}
}
public String LastName
{
get { return _lastName; }
set
{
if (value != _lastName)
{
_lastName = value;
RaisePropertyChanged("LastName");
}
}
}
public Address CustomerAddress
{
get { return _customerAddress; }
set
{
if (value != _customerAddress)
{
_customerAddress = value;
RaisePropertyChanged("CustomerAddress");
}
}
}
private void RaisePropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
Address(Model)
namespace SampleMVVM.Models
{
class Address : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string _addressLine1;
private string _addressLine2;
private string _city;
//private string _selectedState;
private string _postalCode;
private string _country;
public String AddressLine1
{
get { return _addressLine1; }
set
{
if (value != _addressLine1)
{
_addressLine1 = value;
RaisePropertyChanged(AddressLine1);
}
}
}
public String AddressLine2
{
get { return _addressLine2; }
set
{
if (value != _addressLine2)
{
_addressLine2 = value;
RaisePropertyChanged(AddressLine2);
}
}
}
public String City
{
get { return _city; }
set
{
if (value != _city)
{
_city = value;
RaisePropertyChanged(City);
}
}
}
public String PostalCode
{
get { return _postalCode; }
set
{
if (value != _postalCode)
{
_postalCode = value;
RaisePropertyChanged(PostalCode);
}
}
}
public String Country
{
get { return _country; }
set
{
if (value != _country)
{
_country = value;
RaisePropertyChanged(Country);
}
}
}
private void RaisePropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
CustomerViewModel:
namespace SampleMVVM.ViewModels
{
class CustomerViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private Customer _customer;
RelayCommand _saveCommand;
private List<String> _stateList = new List<string>();
private string _selectedState;
private ObservableCollection<Customer> _customerList = new ObservableCollection<Customer>();
//public CustomerViewModel(ObservableCollection<Customer> customers)
//{
// _customers = new ListCollectionView(customers);
//}
public Customer CustomerModel
{
get { return _customer; }
set
{
if (value != _customer)
{
_customer = value;
RaisePropertyChanged("CustomerModel");
}
}
}
public List<String> StateList
{
get
{
return _stateList;
}
set { _stateList = value; }
}
public ObservableCollection<Customer> CustomerList
{
get
{
return _customerList;
}
set
{
if (value != _customerList)
{
_customerList = value;
RaisePropertyChanged("CustomerList");
}
}
}
public CustomerViewModel()
{
CustomerModel = new Customer
{
FirstName = "Fred",
LastName = "Anders",
CustomerAddress = new Address
{
AddressLine1 = "Northeastern University",
AddressLine2 = "360, Huntington Avenue",
City = "Boston",
PostalCode = "02115",
Country = "US",
}
};
StateList = new List<String>
{
"Alaska", "Arizona", "California", "Connecticut", "Massachusetts", "New Jersey", "Pennsylvania", "Texas"
};
SelectedState = StateList.FirstOrDefault();
}
public String SelectedState
{
get { return _selectedState; }
set
{
if (value != _selectedState)
{
_selectedState = value;
RaisePropertyChanged(SelectedState);
}
}
}
private void RaisePropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
CustomerInfo.xaml(view)
<UserControl x:Class="SampleMVVM.Views.CustomerInfo"
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"
xmlns:ViewModels="clr-namespace:SampleMVVM.ViewModels"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.DataContext>
<ViewModels:CustomerViewModel />
</UserControl.DataContext>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<!--Starting label-->
<TextBlock FontSize="18" FontFamily="Comic Sans MS" FontWeight="ExtraBlack"
Foreground="Navy"
Grid.Row="0" HorizontalAlignment="Center">
<TextBlock.Text>
Customer Information:
</TextBlock.Text>
</TextBlock>
<TextBlock Text="First name: " Grid.RowSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top"
Grid.Row="1" Width="80px" Height="50px" Margin="40,5,0,0"/>
<TextBox Text="{Binding CustomerModel.FirstName}" Grid.RowSpan="2" HorizontalAlignment="Left"
VerticalAlignment="Top"
Grid.Row="1" Grid.Column="1" Width="80px" Height="20px" Margin="20,5,0,0" Name="fname"/>
<TextBlock Text="Last Name: " Grid.RowSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top"
Grid.Row="2" Width="80px" Height="50px" Margin="40,5,0,0"/>
<TextBox Text="{Binding CustomerModel.LastName}" Grid.RowSpan="2" HorizontalAlignment="Left"
VerticalAlignment="Top"
Grid.Row="2" Grid.Column="1" Width="80px" Height="20px" Margin="20,5,0,0" Name="lname"/>
<TextBlock Text="Address: " Grid.RowSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top"
Grid.Row="3" Width="80px" Height="50px" Margin="40,5,0,0"/>
<TextBox Text="{Binding CustomerModel.CustomerAddress.AddressLine1}" Grid.RowSpan="2" HorizontalAlignment="Left"
VerticalAlignment="Top"
Grid.Row="3" Grid.Column="1" Width="160px" Height="20px" Margin="20,5,0,0"/>
<TextBox Text="{Binding CustomerModel.CustomerAddress.AddressLine2}" Grid.RowSpan="2" HorizontalAlignment="Left"
VerticalAlignment="Top"
Grid.Row="4" Grid.Column="1" Width="160px" Height="30px" Margin="20,5,0,0"/>
<TextBlock Text="City: " Grid.RowSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top"
Grid.Row="5" Width="80px" Height="20px" Margin="40,5,0,0"/>
<TextBox Text="{Binding CustomerModel.CustomerAddress.City}" Grid.RowSpan="2" HorizontalAlignment="Left"
VerticalAlignment="Top"
Grid.Row="5" Grid.Column="1" Width="80px" Height="20px" Margin="20,5,0,0"/>
<TextBlock Text="State: " Grid.RowSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top"
Grid.Row="6" Width="80px" Height="20px" Margin="40,5,0,0"/>
<ComboBox Grid.RowSpan="2" HorizontalAlignment="Left" Name="listOfSates"
VerticalAlignment="Top"
Grid.Row="6" Grid.Column="1" Width="80px" Height="20px" Margin="20,5,0,0"
ItemsSource="{Binding Path=StateList}"
SelectedItem="{Binding Path=SelectedState}"
SelectionChanged="ComboBox_SelectionChanged"
>
</ComboBox>
<TextBlock Text="PostalCode: " Grid.RowSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top"
Grid.Row="7" Width="80px" Height="20px" Margin="40,5,0,0"/>
<TextBox Text="{Binding CustomerModel.CustomerAddress.PostalCode}" Grid.RowSpan="2" HorizontalAlignment="Left"
VerticalAlignment="Top"
Grid.Row="7" Grid.Column="1" Width="80px" Height="20px" Margin="20,5,0,0"/>
<TextBlock Text="Country: " Grid.RowSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top"
Grid.Row="8" Width="80px" Height="20px" Margin="40,5,0,0"/>
<TextBox Text="{Binding CustomerModel.CustomerAddress.Country}" Grid.RowSpan="2" HorizontalAlignment="Left"
VerticalAlignment="Top"
Grid.Row="8" Grid.Column="1" Width="80px" Height="20px" Margin="20,5,0,0"/>
<Button Content="Save" Grid.RowSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top"
Grid.Row="9" Width="50px" Height="20px" Name="savebtn" Margin="40,5,0,0"
Click="savebtn_Click"/>
<ListBox Name="cList" ItemsSource="{Binding Path=CustomerList}"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Grid.Row="1" Grid.Column="2" Grid.RowSpan="2" Width="200px" Height="300px" Margin="200,5,0,0">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding CustomerModel.FirstName}"
FontWeight="Bold" Foreground="Navy"/>
<TextBlock Text=", " />
<TextBlock Text="{Binding CustomerModel.LastName}"
FontWeight="Bold" Foreground="Navy"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
CustomerInfo(Code behind class)
namespace SampleMVVM.Views
{
/// <summary>
/// Interaction logic for CustomerInfo.xaml
/// </summary>
public partial class CustomerInfo : UserControl
{
public CustomerInfo()
{
InitializeComponent();
//checkvalue();
}
private void savebtn_Click(object sender, RoutedEventArgs e)
{
////Customer c = new Customer();
////c.FirstName = fname.Text;
////c.LastName = lname.Text;
//CustomerViewModel cvm = new CustomerViewModel();
//cvm.CustomerModel.FirstName = fname.Text;
//cvm.CustomerModel.LastName = lname.Text;
//List<CustomerViewModel> customerList = new List<CustomerViewModel>();
//customerList.Add(cvm);
var viewModel = DataContext as CustomerViewModel;
if (viewModel != null)
{
//viewModel.ShowCustomerInfo();
String strfname = viewModel.CustomerModel.FirstName;
String strname = viewModel.CustomerModel.LastName;
viewModel.CustomerList.Add(viewModel.CustomerModel);
String str1 = viewModel.CustomerList.FirstOrDefault().FirstName;
int i = viewModel.CustomerList.Count();
//cList.ItemsSource = viewModel.CustomerList;
}
}
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
CustomerViewModel cvm = new CustomerViewModel();
cvm.SelectedState = listOfSates.SelectedItem.ToString();
}
}
}
I just cant understand where am I going wrong...Someone please help
And for the correct binding in ListBox.ItemTemplate:
<TextBlock Text="{Binding FirstName}"
FontWeight="Bold" Foreground="Navy"/>
<TextBlock Text="{Binding LastName}"
FontWeight="Bold" Foreground="Navy"/>
The DataContext of ListBoxItem is a Customer already.
You only create a new instance of a CustomerModel object once in your code (in the Customer View Model constructor). So you are constantly updating the same customer object rather than creating a new one.
At the end of your click handler you should do a
viewModel.CustomerModel = new Customer();
HOWEVER
Rather than having a click handler you should have an ICommand in your view model for adding a new customer. Then you should bind to command of your button to the ICommand in your view model.
you were binding the CustomerLIst.FirstName which is not walid because innterconent will check for property name customerlist in side the listbox itemssource. and as its not their then it will raise a silent error but wo't show into GUI, what you need to do is just provide the propertyname like firstname and lastname that will work.
well besides your binding in listbox every thing else is ok. just replace you listbox binding as like below.
<TextBlock Grid.Row="0"
Grid.Column="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Text="List of Customers" />
<ListBox Name="cList"
Grid.Row="1"
Grid.RowSpan="8"
Grid.Column="2"
ItemsSource="{Binding CustomerList}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock FontWeight="Bold"
Foreground="Black"
Text="{Binding FirstName}" />
<TextBlock Text=", " />
<TextBlock FontWeight="Bold"
Foreground="Black"
Text="{Binding LastName}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<TextBlock Grid.Row="10"
Grid.Column="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Text="{Binding CustomerList.Count,
StringFormat='Total Customers, ={0}'}" />
better to take command insteed of events.
Your problem is in this line of code:
RaisePropertyChanged("CustomerList");
It doesn't work for collection add/remove events. Take a look at ObservableCollection and Item PropertyChanged.
Keep in mind that in MVVM, you should not have much code (if any) in code behind. Consider using commands.

SelectedItem for combobox is always null

I'm working on Silverlight 4, and I have difficulties to make my combobox work correctly.
On changing selected items, selectedItem value stays null. I defined combobox as following:
<ComboBox
x:Name="ProductGroupCombobox"
Grid.Row="2"
Margin="10,15"
Height="30" Width="200"
Background="{x:Null}"
BorderBrush="{x:Null}"
ItemsSource="{Binding}"
SelectionChanged="ProductGroupCombobox_SelectionChanged"
SelectedItem="{Binding Path=ProductType, Mode=TwoWay}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Name}" />
</DataTemplate>
<ComboBox.ItemTemplate>
</ComboBox>
Does anyone have idea?
Your SelectedItem property needs to be bound to an instance in your collection, whereas it appears you have your DataContext set to what I am assuming is a collection. Note how I adjusted the binding to be that of the collection and a separate property to be that of an instance within the collection.
public class MyData : INotifyPropertyChanged
{
List<String> ProductTypes {get; set;}
String _selectedProductType = String.Empty;
String SelectedProductType
{
get
{
return _selectedProductType;
}
set
{
_selectedProductType = value;
PropertyChangedEventHandler handler = PropertyChanged;
if(handler != null)
handler(this, new PropertyChangedEventArgs("SelectedProductType");
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
...
this.DataContext = new MyData();
...
<ComboBox
x:Name="ProductGroupCombobox"
Grid.Row="2"
Margin="10,15"
Height="30" Width="200"
Background="{x:Null}"
BorderBrush="{x:Null}"
ItemsSource="{Binding ProductTypes}"
SelectionChanged="ProductGroupCombobox_SelectionChanged"
SelectedItem="{Binding Path=SelectedProductType, Mode=TwoWay}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Name}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>

Resources