I am trying to create a simple WPF application and bind data to combobox but I am not having any luck. My PeriodList is getting populated fine but is not getting bind to the combobox. Do I need to set the DataContext in XAML or in code behind? Please help, I am very confused.
Here is my XAML
<UserControl x:Class="FinancialControlApp.KeyClientReportView"
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:local="clr-namespace:FinancialControlApp"
mc:Ignorable="d"
d:DesignHeight="300" Width="630">
<UserControl.Resources>
<!-- DataTemplate (View) -->
<DataTemplate DataType="{x:Type local:KeyClientReportModel}">
</DataTemplate>
</UserControl.Resources>
<DockPanel Margin="20">
<DockPanel DockPanel.Dock="Top" VerticalAlignment="Center">
<TextBlock Margin="10,2" DockPanel.Dock="Left" Text="Start Period" VerticalAlignment="Center" />
<ComboBox Name="cmbStartPeriod" Margin="10,2" Width="112" VerticalAlignment="Center" ItemsSource="{Binding PeriodList}">
</ComboBox>
<TextBlock Margin="10,2" DockPanel.Dock="Left" Text="End Period" VerticalAlignment="Center" />
<ComboBox Name="cmbEndPeriod" Margin="10,2" Width="112" VerticalAlignment="Center" ItemsSource="{Binding PeriodList}" />
<!--<Button Content="Save Product" DockPanel.Dock="Right" Margin="10,2" VerticalAlignment="Center"
Command="{Binding Path=SaveProductCommand}" Width="100" />-->
<Button Content="Run" DockPanel.Dock="Left" Margin="10,2"
Command="{Binding Path=GetProductCommand}" IsDefault="True" Width="100" />
</DockPanel>
<!--<ContentControl Margin="10" Content="{Binding Path=PeriodName}" />-->
<ContentControl Margin="10"></ContentControl>
</DockPanel>
</UserControl>
Here is my model
namespace FinancialControlApp
{
public class KeyClientReportModel : ObservableObject
{
private string _periodName;
public string PeriodName
{
get { return _periodName; }
set
{
if (value != _periodName)
{
_periodName = value;
OnPropertyChanged("PeriodName");
}
}
}
List<KeyClientReportModel> _periodList = new List<KeyClientReportModel>();
public List<KeyClientReportModel> PeriodList
{
get { return _periodList; }
set
{
_periodList = value;
OnPropertyChanged("PeriodList");
}
}
}
}
And here is my ViewModel
namespace FinancialControlApp
{
public class KeyClientReportViewModel : ObservableObject, IPageViewModel
{
private KeyClientReportModel _currentPeriod;
private ICommand _getReportCommand;
private ICommand _saveReportCommand;
public KeyClientReportViewModel()
{
GetPeriod();
}
public string Name
{
get { return "Key Client Report"; }
}
public ObservableCollection<KeyClientReportModel> _periodName;
public ObservableCollection<KeyClientReportModel> PeriodName
{
get { return _periodName; }
set
{
if (value != _periodName)
{
_periodName = value;
OnPropertyChanged("PeriodName");
}
}
}
private void GetPeriod()
{
DataSet ds = new DataSet();
DataTable dt = new DataTable();
Helper_Classes.SQLHelper helper = new Helper_Classes.SQLHelper();
ds = helper.getPeriod();
dt = ds.Tables[0];
PeriodName = new ObservableCollection<KeyClientReportModel>();
foreach (DataRow dr in dt.Rows)
{
var period = dr["Period"].ToString();
if (period != null)
{
PeriodName.Add(new KeyClientReportModel { PeriodName = period });
}
//p.PeriodName = dr["Period"].ToString();
}
}
}
}
UPDATE: So I attach a Value Converter to Break into the Debugger and here is what I see. I see
Change
ItemsSource="{Binding KeyClientReportModel.PeriodList}"
To:
ItemsSource="{Binding PeriodList}"
Make sure your ViewModel
is set to the DataContext
property of your view.
Set the combobox DisplayMemberPath
to the property Name
of your KeyClientReportViewModel
class.
Or alternatively override the .ToString()
method inside the KeyClientReportViewModel
class in order to provide the Combobox
item display text.
This can help you
------View
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
<!-- To get the ViewModel -->
xmlns:viewmodels="clr-namespace:WpfApp1.ViewModels"
Title="MainWindow">
<Window.DataContext>
<!-- Assigning the ViewModel to the View -->
<viewmodels:MainWindowViewModel />
</Window.DataContext>
<DockPanel VerticalAlignment="Center"
DockPanel.Dock="Top">
<TextBlock Margin="10,2"
VerticalAlignment="Center"
DockPanel.Dock="Left"
Text="Start Period" />
<ComboBox Name="cmbStartPeriod"
Width="112"
Margin="10,2"
VerticalAlignment="Center"
ItemsSource="{Binding PeriodName}" // Items in the ViewModel
DisplayMemberPath="Name"/> // Property to display
</DockPanel>
</Window>
------- ViewModel
public class MainWindowViewModel
{
public MainWindowViewModel()
{
var items = new List<KeyClientReportModel>
{
new KeyClientReportModel
{
Name = "First",
Value = 1
},
new KeyClientReportModel
{
Name = "Second",
Value = 1
}
};
PeriodName = new ObservableCollection<KeyClientReportModel>(items);
}
// You don't need to notify changes here because ObservableCollection
// send a notification when a change happens.
public ObservableCollection<KeyClientReportModel> PeriodName { get; set; }
}
public class KeyClientReportModel
{
public int Value { get; set; }
public string Name { get; set; }
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.