Getting content from WPF GridViewColumn through Button - wpf

I have a Button within a GridView within a ListView. When the button is clicked, I would like to get the text from the corresponding row of the Grid View for that button. Can anyone help me with the code for this?
My XAML is:
<ListView Name="resultList" ItemsSource="{Binding}" DockPanel.Dock="Top">
<ListView.View>
<GridView AllowsColumnReorder="true" ColumnHeaderToolTip="Test Results Summary">
<GridViewColumn DisplayMemberBinding= "{Binding Date}" Header="Date" Width="Auto"/>
<GridViewColumn DisplayMemberBinding= "{Binding Status}" Header="Status" Width="Auto"/>
<GridViewColumn Header="" Width="Auto">
<GridViewColumn.CellTemplate>
<DataTemplate >
<Button x:Name="btnRemoveTest" Click="_viewResult" Content="View" Height="20" Width="100"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
What can I do in here:
private void _viewResult(object sender, RoutedEventArgs e)
{
}

Use DataContext of Buttonas shown below. Please note that here in this example code, I'm using Customer.
private void _viewResult(object sender, RoutedEventArgs e)
{
Button button = sender as Button;
Customer cust = button.DataContext as Customer;
string sDate = cust.Date;
string sStatus = cust.Status;
}
Below is the complete working code.
MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace ListViewButtonClick
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
resultList.ItemsSource = new Customers();
}
private void _viewResult(object sender, RoutedEventArgs e)
{
Button button = sender as Button;
Customer cust = button.DataContext as Customer;
string sDate = cust.Date;
string sStatus = cust.Status;
}
}
public class Customer
{
public String Date { get; set; }
public String Status { get; set; }
public Customer(String Date, String Status)
{
this.Date = Date;
this.Status = Status;
}
}
public class Customers : ObservableCollection<Customer>
{
public Customers()
{
Add(new Customer("11/23/2015", "in progress"));
Add(new Customer("11/24/2015", "Done"));
Add(new Customer("11/22/2015", "Not yet done"));
}
}
}
MainWindow.xaml
<Window x:Class="ListViewButtonClick.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">
<Grid>
<ListView Name="resultList" DockPanel.Dock="Top">
<ListView.View>
<GridView AllowsColumnReorder="true" ColumnHeaderToolTip="Test Results Summary">
<GridViewColumn DisplayMemberBinding= "{Binding Date}" Header="Date" Width="Auto"/>
<GridViewColumn DisplayMemberBinding= "{Binding Status}" Header="Status" Width="Auto"/>
<GridViewColumn Header="" Width="Auto">
<GridViewColumn.CellTemplate>
<DataTemplate >
<Button x:Name="btnRemoveTest" Click="_viewResult" Content="View" Height="20" Width="100"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
</Window>

Related

GridViewColumnHeader doesn't appear

I have a WPF form with some GridViewColumns in them to display the data. However, even though I set the Header property in each column, the headers never appear.
XAML:
<Window x:Class="MyProject.ViewModel.MyClassView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:MyProject.ViewModel"
Title="Title" Height="210.4" Width="500" ResizeMode="NoResize"
WindowStartupLocation="CenterOwner" WindowStyle="ToolWindow">
<Window.Resources>
<DataTemplate x:Key="tempA">
<TextBlock Text="{Binding Path=dataA}"/>
</DataTemplate>
<DataTemplate x:Key="tempB">
<TextBlock Text="{Binding Path=dataB}"/>
</DataTemplate>
<DataTemplate x:Key="tempC">
<TextBlock Text="{Binding Path=dataC}"/>
</DataTemplate>
</Window.Resources>
<Grid Margin="5,5,5,5">
<ListView x:Name="MyList" ItemsSource="{Binding MyDataCollection}" MouseDoubleClick="ListView_MouseDoubleClick">
<ListView.View>
<GridView>
<GridViewColumn x:Name="colA" Header="Name" Width="100" CellTemplate="{StaticResource tempA}"/>
<GridViewColumn x:Name="colB" Header="Type" Width="100" CellTemplate="{StaticResource tempB}"/>
<GridViewColumn x:Name="colC" Header="Diameter" Width="100" CellTemplate="{StaticResource tempC}"/>
</GridView>
</ListView.View>
</ListView>
</Grid>
</Window>
Code-behind:
namespace MyProject.ViewModel
{
public partial class MyClassView : Window
{
public object SelectedItem = null;
public MyClassView()
{
InitializeComponent();
}
private void ListView_MouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
SelectedItem = MyList.SelectedItem;
}
}
}
ViewModel:
namespace MyProject.ViewModel
{
public class MyViewModel : INotifyPropertyChanged
{
public string Type { get; set; }
public object MyDataCollection { get; set; }
public MyViewModel(object collection, string type)
{
Type = type;
MyDataCollection = collection;
}
internal void RaisePropertyChanged(string prop)
{
if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(prop)); }
}
public event PropertyChangedEventHandler PropertyChanged;
}
}
The object that is passed into the ViewModel constructor is guaranteed to contain dataA, dataB and dataC among others.
Could someone explain why the headers in my GridView aren't appearing?
Try using a DataGrid instead.
It would look something like this:
<DataGrid ItemsSource="{Binding MyDataCollection}" AutoGenerateColumns="False" >
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Name}" IsReadOnly="True"/>
<DataGridComboBoxColumn Header="Type" ItemsSource="{Binding TypeList}" SelectedItemBinding="{Binding Type}"/>
...
</DataGrid.Columns>
</DataGrid>

After move the GridSplitter, the layout don't work correctly

My purpose is that: double-click the TabItem named "Tab" in the TabControl, then the TabControl will be folded, another double-click lead to unfolded.
But after I move the GridSplitter and double-click the "Tab" to be folded, it don't work correctly that the the height of the column the TabControl in isn't equal to the height of the TabControl, in other word, GridSplitter don't follow the "TabControl".
.xaml
<Window x:Class="WpfApplication7.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">
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto" MinHeight="20"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid Grid.Column="1">
<Label>
Nothing
</Label>
</Grid>
</Grid>
<GridSplitter Grid.Row="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
Height="6" />
<TabControl Grid.Row="2"
TabStripPlacement="Bottom"
VerticalAlignment="Stretch">
<TabItem Header="Tab"
MouseDoubleClick="TabItemDoubleCilck">
<!--ListView-->
<ListView Grid.Row="1"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<ListView.View>
<GridView>
<GridViewColumn Header="AA "
Width="100"
DisplayMemberBinding="{Binding [0]}" />
<GridViewColumn Header="BB"
Width="100"
DisplayMemberBinding="{Binding [1]}" />
<GridViewColumn Header="CC"
Width="100"
DisplayMemberBinding="{Binding [2]}" />
<GridViewColumn Header="DD"
Width="100"
DisplayMemberBinding="{Binding [3]}" />
</GridView>
</ListView.View>
<ListViewItem>
<x:Array Type="sys:String" >
<sys:String>2000/01/01</sys:String>
<sys:String>2000/01/01</sys:String>
<sys:String>2000/01/01</sys:String>
<sys:String>2000/01/01</sys:String>
</x:Array>
</ListViewItem>
<ListViewItem>
<x:Array Type="sys:String" >
<sys:String>2000/01/01</sys:String>
<sys:String>2000/01/01</sys:String>
<sys:String>2000/01/01</sys:String>
<sys:String>2000/01/01</sys:String>
</x:Array>
</ListViewItem>
</ListView>
</TabItem>
</TabControl>
</Grid>
</Window>
.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApplication7
{
/// <summary>
/// MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
const double dBottomTabMinHeight = 20.0;
private bool isBottomTabUnfold;
public MainWindow()
{
InitializeComponent();
isBottomTabUnfold = true;
}
private void TabItemDoubleCilck(object sender, MouseButtonEventArgs e)
{
TabItem tabItm = sender as TabItem;
if (isBottomTabUnfold)
{
((FrameworkElement)tabItm.Parent).Height = dBottomTabMinHeight;
}
else
{
((FrameworkElement)tabItm.Parent).Height = Double.NaN;
}
isBottomTabUnfold = !isBottomTabUnfold;
}
}
}
try this, hope this is what you expected
private void TabItemDoubleCilck(object sender, MouseButtonEventArgs e)
{
TabItem tabItm = sender as TabItem;
if (isBottomTabUnfold)
{
((FrameworkElement)tabItm.Parent).Height = dBottomTabMinHeight;
((FrameworkElement)tabItm.Parent).VerticalAlignment = System.Windows.VerticalAlignment.Bottom;
}
else
{
((FrameworkElement)tabItm.Parent).Height = Double.NaN;
((FrameworkElement)tabItm.Parent).VerticalAlignment = System.Windows.VerticalAlignment.Stretch;
}
isBottomTabUnfold = !isBottomTabUnfold;
}
edit:
like this then?
private void TabItemDoubleCilck(object sender, MouseButtonEventArgs e)
{
TabItem tabItm = sender as TabItem;
if (isBottomTabUnfold)
{
dUnfoldedHeight = ((FrameworkElement)tabItm.Parent).ActualHeight;
((FrameworkElement)tabItm.Parent).Height = dBottomTabMinHeight;
rowTab.Height = new GridLength(1, GridUnitType.Auto);
}
else
{
((FrameworkElement)tabItm.Parent).Height = double.NaN;
rowTab.Height = new GridLength(dUnfoldedHeight);
}
isBottomTabUnfold = !isBottomTabUnfold;
}
NB:
rowTab is the name of the 3rd rowdefinition, dUnfoldedHeight is a private member to track the height of the unfolded tab before it's folded.
you might find a weird behavior on dragging the splitter up when the tab is folded or when dragging the spliiter down until the tab is look like unfolded, to fix this you probably have to work with the DragDelta and DragCompleted event of the splitter to decide whether in the end the tab should be considered as folded or not

If datagrid hasn't been shown, I can't set in it current position row (silverlight)

i have application with two Tabs. on first tab placed button which sets the current position in dataGrid1 on second tab. While i won't show a second tab, i can't set current position by button1.
<UserControl x:Class="SilverlightApplication9.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400" xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk">
<Grid x:Name="LayoutRoot" Background="White">
<sdk:TabControl Height="234" HorizontalAlignment="Left" Margin="52,44,0,0" Name="tabControl1" VerticalAlignment="Top" Width="326">
<sdk:TabItem Header="tabItem1" Name="tabItem1">
<Grid>
<Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="74,44,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
</Grid>
</sdk:TabItem>
<sdk:TabItem Header="tabItem2" Name="tabItem2">
<Grid>
<sdk:DataGrid ItemsSource="{Binding strs}" RowBackground="White" AutoGenerateColumns="False" Height="141" HorizontalAlignment="Left" Margin="36,12,0,0" Name="dataGrid1" VerticalAlignment="Top" Width="199">
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn Binding="{Binding}" CanUserReorder="True" CanUserResize="True" CanUserSort="True" Width="Auto" />
</sdk:DataGrid.Columns>
</sdk:DataGrid>
</Grid>
</sdk:TabItem>
</sdk:TabControl>
</Grid>
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
namespace SilverlightApplication9
{
public partial class MainPage : UserControl
{
private ObservableCollection<string> _strs = new ObservableCollection<string>();
public ObservableCollection<string> strs { get { return _strs; } set { _strs = value; } }
public MainPage()
{
this.DataContext = this;
InitializeComponent();
strs.Add("1");
strs.Add("2");
strs.Add("3");
strs.Add("4");
strs.Add("5");
}
private void button1_Click(object sender, RoutedEventArgs e)
{
dataGrid1.SelectedIndex = 2;
}
}
}
The problem is that the DataGrid isn't loaded when you attempt to set the SelectedIndex in the button click handler if you haven't already navigated to the tab that contains the DataGrid.
The way to achieve what you want is to use data binding. You will also want to implement INotifyPropertyChanged for any subsequent changes to the property you bind DataGrid.SelectedIndex to. The following is a rough example of how to do what you want in the code you provided.
public partial class MainPage : UserControl, INotifyPropertyChanged
{
private ObservableCollection<string> _strs
= new ObservableCollection<string>();
public ObservableCollection<string> strs
{
get { return _strs; }
set { _strs = value; }
}
public MainPage()
{
this.DataContext = this;
InitializeComponent();
strs.Add("1");
strs.Add("2");
strs.Add("3");
strs.Add("4");
strs.Add("5");
SelectedIndex = 0;
}
private int _selectedIndex;
public int SelectedIndex
{
get { return _selectedIndex; }
set
{
_selectedIndex = value;
var pChanged = PropertyChanged;
if (pChanged != null)
pChanged(this, new PropertyChangedEventArgs("SelectedIndex"));
}
}
private void button1_Click(object sender, RoutedEventArgs e)
{
SelectedIndex ++;
}
public event PropertyChangedEventHandler PropertyChanged;
}
Then update your DataGrid definition in xaml to:
<sdk:DataGrid ItemsSource="{Binding strs}"
SelectedIndex="{Binding SelectedIndex, Mode=TwoWay}"
RowBackground="White"
AutoGenerateColumns="False"
Height="141"
HorizontalAlignment="Left"
Margin="36,12,0,0"
Name="dataGrid1"
VerticalAlignment="Top"
Width="199">
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn Binding="{Binding}"
CanUserReorder="True"
CanUserResize="True"
CanUserSort="True"
Width="Auto" />
</sdk:DataGrid.Columns>
</sdk:DataGrid>

custom control in DataGridTemplateColumn

I'd like to add my custom control into a template column of data grid.
The custom control is very similar to a text box, but has an icon in it. The user can click the icon, and selects an item from a prompted window, then the selected item will be filled into the text box.
My problem is when the text box is filled, after I click the second column, the text will disappear. If I replace the custom control with a simple text box, the result is the same.
Here is the sample code:
//Employee.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SimpleGridTest
{
public class Employee
{
public string Department { get; set; }
public int ID { get; set; }
public string Name { get; set; }
}
}
Mainwindow.xaml
<Window x:Class="SimpleGridTest.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">
<Grid>
<DataGrid x:Name="grid" Grid.Row="1" Margin="5" AutoGenerateColumns="False"
RowHeight="25" RowHeaderWidth="10"
ItemsSource="{Binding}"
CanUserAddRows="True" CanUserSortColumns="False">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Department" Width="150">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding Department}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="ID" Binding="{Binding Path=ID}"
Width="100"/>
<DataGridTextColumn Header="Name"
Binding="{Binding Path=Name}"
Width="200"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
MainWindow.xaml.cs
using System.Windows;
using System.Collections.ObjectModel;
namespace SimpleGridTest
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private ObservableCollection<Employee> _employees = new ObservableCollection<Employee>();
public ObservableCollection<Employee> Employees
{
get { return _employees; }
set { _employees = value; }
}
public MainWindow()
{
InitializeComponent();
grid.ItemsSource = Employees;
}
}
}
How can I fix this problem? Or I need to write a DataGrid***Column as DataGridTextColumn? Thanks in advance!
Best Regards,
Johnson
I guess you have to specify a CellEditingTemplate for editing and to display content you have to specify a normal celltemplate
<Controls:DataGridTemplateColumn Header="Department" Width="150">
<Controls:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Department}" />
</DataTemplate>
</Controls:DataGridTemplateColumn.CellTemplate>
<Controls:DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<TextBox Text="{Binding Department}"/>
</DataTemplate>
</Controls:DataGridTemplateColumn.CellEditingTemplate>
</Controls:DataGridTemplateColumn>
Hope this helps..

wpf my UI doesnt refrash

my xml is :
<Window.Resources>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</Window.Resources>
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="381*" />
<ColumnDefinition Width="20*" />
<ColumnDefinition Width="101*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="110*" />
<RowDefinition Height="201*" />
</Grid.RowDefinitions>
<StackPanel Margin="320,0,0,0" Grid.RowSpan="2">
<ListView ItemsSource="{Binding employeeCollection}">
<ListView.View>
<GridView>
<GridViewColumn Header="Employee ID" DisplayMemberBinding="{Binding Path=EmployeeID}"/>
<GridViewColumn Header="First Name" DisplayMemberBinding="{Binding Path=FirstName}"/>
<GridViewColumn Header="Last Name" DisplayMemberBinding="{Binding Path=LastName}"/>
<GridViewColumn Header="start" DisplayMemberBinding="{Binding Path=startHR}"/>
<GridViewColumn Header="finish" DisplayMemberBinding="{Binding Path=finishHR}">
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</StackPanel>
<StackPanel Margin="2,0,0,137" Grid.RowSpan="2" Grid.ColumnSpan="2" Grid.Column="1">
<ListBox FontFamily="Guttman Yad-Brush" BorderBrush="AliceBlue" BorderThickness="5" ItemsSource="{Binding Path=dateItems}" DisplayMemberPath="Name" SelectedValuePath="Name" SelectedValue="{Binding Path=dateItem}" Width="233" Height="164" />
</StackPanel>
<Button Click="Button_Click" Width="102" Height="34" Margin="0,98,-1,69" Grid.Row="1" Grid.Column="2" Content="בחר" FontFamily="Guttman Yad-Brush" Background="AliceBlue"></Button>
<TextBox Name="dateTextBox" Grid.Column="1" Margin="26,152,0,33" Grid.Row="1" FontFamily="Guttman Yad-Brush" Grid.ColumnSpan="2" />
<Calendar SelectedDate="{Binding Path=SelectedDate}" Height="168" Name="calendar1" Width="182" SelectedDatesChanged="calendar1_SelectedDatesChanged" Margin="66,68,485,115" Grid.RowSpan="2" />
</Grid>
-->
-->
this is the start window class :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.ComponentModel;
using System.Windows.Data;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApplication1
{
public partial class MainWindow : Window
{
ConnectionViewModel vm;
public MainWindow()
{
InitializeComponent();
vm = new ConnectionViewModel();
DataContext = vm;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
//((ConnectionViewModel)DataContext).dateItems = "test";
if (vm.cm.dateItem.ToString() != null)
{
dateTextBox.Text = vm.cm.dateItem.ToString();
vm.em.insert();
}
}
private void calendar1_SelectedDatesChanged(object sender, SelectionChangedEventArgs e)
{
string []s = calendar1.SelectedDate.ToString().Split(' ');
dateTextBox.Text = s[0];
}
}
public class ConnectionViewModel
{
public DateConectionModule cm;
public employeesGrid em;
public ConnectionViewModel()
{
cm = new DateConectionModule();
em = new employeesGrid();
}
public CollectionView dateItems
{
get { return cm.dateItems; }
}
public string dateItem
{
get {return cm.dateItem;}
set{ cm.dateItem = value;}
}
public CollectionView employeeCollection
{
get { return em.employeeCollection; }
}
}
public class DateConectionModule : INotifyPropertyChanged
{
public static string[] datesString = { "01.01.2011", "02.01.2011", "03.01.2011", "04.01.2011", "05.01.2011" };
public DateConectionModule()
{
employeesGrid em = new employeesGrid();
IList<dateItem> list = new List<dateItem>();
//query to database should be here
foreach (string dataString in datesString)
{
list.Add(new dateItem(dataString));
}
_dateItemList = new CollectionView(list);
}
private readonly CollectionView _dateItemList;
private string m_dateItem;
public CollectionView dateItems
{
get { return _dateItemList; }
}
public string dateItem
{
get { return m_dateItem; }
set
{
if (m_dateItem == value)
return;
m_dateItem = value;
OnPropertyChanged("dateItem");
}
}
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
public class dateItem
{
public string Name { get; set; }
public dateItem(string name)
{
Name = name;
}
}
public class employeesGrid : INotifyPropertyChanged
{
private CollectionView _dateItemList;
private string m_dateItem;
public employeesGrid()
{
IList<employiesData> list = new List<employiesData>();
//query to database should be here
list.Add(new employiesData{
EmployeeID = "036854768",
FirstName = "yoav" ,
LastName = "stern",
startHR = "1600" ,
finishHR = "0200"});
_dateItemList = new CollectionView(list);
}
public void insert()
{
IList<employiesData> list = new List<employiesData>();
//query to database should be here
list.Add(new employiesData
{
EmployeeID = "0234235345",
FirstName = "shoki",
LastName = "zikri",
startHR = "1600",
finishHR = "0200"
});
_dateItemList = new CollectionView(list);
OnPropertyChanged("employeeCollection");
}
public CollectionView employeeCollection
{
get { return _dateItemList; }
set
{
if (_dateItemList == value)
return;
_dateItemList = value;
OnPropertyChanged("employeeCollection");
}
}
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
public class employiesData
{
public string EmployeeID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string startHR { get; set; }
public string finishHR { get; set; }
}
}
1.i want thar when insertTest is called the UI will load my new values
2.this is my first wpf work so any advices on how to make things more readable,effican,simple and notes about the my poor architecture i know it's crapy can some
Below my points
1- What is the use of ConnectionViewModel class , it is just warpping DataConnectionViewModel so i would suggest that you can get rid of ConnectionViewModel() and use DataConnectionViewModel.
2-i think you can Get rid of employeesGrid class because all you need a collection of employees so rather than useing a seprate collection class, make an observrablecollection in DataConnectionViewModel() class.
3- Use Wpf- Model -View-ViewModel Template this gives you better idea
4- i have just refacror your code and create a similar application which uses MVVM and ObservableCollection and much simpler to use.
my xaml
<Window.Resources>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
</Style>
</Window.Resources>
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="381*" />
<ColumnDefinition Width="20*" />
<ColumnDefinition Width="101*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="110*" />
<RowDefinition Height="201*" />
</Grid.RowDefinitions>
<StackPanel Margin="320,0,0,0" Grid.RowSpan="2">
<ListView ItemsSource="{Binding EmpList}">
<ListView.View>
<GridView>
<GridViewColumn Header="Employee ID" DisplayMemberBinding="{Binding Path=EmployeeID}"/>
<GridViewColumn Header="First Name" DisplayMemberBinding="{Binding Path=FirstName}"/>
<GridViewColumn Header="Last Name" DisplayMemberBinding="{Binding Path=LastName}"/>
<GridViewColumn Header="start" DisplayMemberBinding="{Binding Path=startHR}"/>
<GridViewColumn Header="finish" DisplayMemberBinding="{Binding Path=finishHR}">
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</StackPanel>
<StackPanel Margin="2,0,0,137" Grid.RowSpan="2" Grid.ColumnSpan="2" Grid.Column="1">
<ListBox FontFamily="Guttman Yad-Brush" BorderBrush="AliceBlue" BorderThickness="5" ItemsSource="{Binding Path=dateItems}" DisplayMemberPath="Name" SelectedValuePath="Name" SelectedValue="{Binding Path=dateItem}" Width="233" Height="164" />
</StackPanel>
<!--<Button Click="Button_Click" Width="102" Height="34" Margin="0,98,-1,69" Grid.Row="1" Grid.Column="2" Content="בחר" FontFamily="Guttman Yad-Brush" Background="AliceBlue"></Button>-->
<TextBox Name="dateTextBox" Grid.Column="1" Margin="26,152,0,33" Grid.Row="1" FontFamily="Guttman Yad-Brush" Grid.ColumnSpan="2" />
<!--<Calendar SelectedDate="{Binding Path=SelectedDate}" Height="168" Name="calendar1" Width="182" SelectedDatesChanged="calendar1_SelectedDatesChanged" Margin="66,68,485,115" Grid.RowSpan="2" />-->
</Grid>
My Code
1-
Create DataConnectionViewModel which is inheriting ViewModelBase class.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Employee.Models;
using System.Collections.ObjectModel;
namespace Employee.ViewModels
{
public class DateConectionModule : ViewModelBase
{
#region " Instance Variables "
public static string[] datesString = { "01.01.2011", "02.01.2011", "03.01.2011", "04.01.2011", "05.01.2011" };
#endregion " Instance Variables "
#region " Constructor "
public DateConectionModule()
{
CreateEmployeeData();
}
#endregion " Constructor "
#region " Public Properties "
public ObservableCollection<EmployeeData> EmpList { get; set; }
#endregion " Public Properties "
#region " Helper Methods "
private void CreateEmployeeData()
{
EmpList = new ObservableCollection<EmployeeData>();
EmpList.Add
(
new EmployeeData() { EmployeeID="1", LastName="Gates", FirstName="Bill", finishHR="", startHR ="" }
);
}
#endregion " Helper Methods "
}
}
2- ViewModelBAse Class
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Input;
namespace Employee.ViewModels
{
///
/// Provides common functionality for ViewModel classes
///
public abstract class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
3- Set the Data Context in the MainWindow.Xaml.cs
public partial class MainView : Window
{
public MainView()
{
InitializeComponent();
this.DataContext = new DateConectionModule();
}
}
there are lot of other things like Dependency Injection, etc.. but for your case , you can write a controller which call your dataservice to give you employess list than assign list to the observablecollection.
4- i can suggest read abot Prism framework which gives you very much flexibility during application management and also in TDD.

Resources