Different values for different comboboxes in Datagrid - c#

Bear with me, as I'm new to WPF.I have a datagrid which contains comboboxes.
<DataGrid x:Name="dgData" AutoGenerateColumns="False" Margin="131,93,13,101" Grid.Column="1" SelectionChanged="dgData_SelectionChanged">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Subject}" Header="Subject" Width="100"/>
<DataGridComboBoxColumn Header="Subject" x:Name="comboboxColumn1"/>
</DataGrid.Columns>
</DataGrid>
And I use the following code to load different itemsources depending on which combobox is clicked on by the user:
private void dgData_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (dgData.SelectedIndex == 0)
{
comboboxColumn1.ItemsSource = resolution;
} else if (dgData.SelectedIndex == 1)
{
comboboxColumn1.ItemsSource = codec;
}
}
How I bind dgData:
List<TicketInfo> ticketsList = new List<TicketInfo>
{
new TicketInfo{ Subject="File", Status="Open"},
new TicketInfo{ Subject="Resolution", Status="Assigned"},
};
dgData.ItemsSource = ticketsList;
public class TicketInfo
{
public string Subject { get; set; }
public string Status { get; set; }
}
Now I also need to retrieve the value of the combobox once the user chooses the value. Is there a more elegant way to load different items in different comboboxes and retrieving the value?
Thanks!

You don't show how you bind dgData.
public class TicketInfo
{
public string Subject { get; set; }
public string Status { get; set; }
public List<string> SubjectSubList { get; set; }
}
Bind the second column to SubjectSubList
When you build List ticketsList just put resolution in the first SubjectSubList and codec in the second.

Related

How to pass value from DB to Listview/Grid View via binding?

I need to pass a value from a database to Listview via a binding. I managed to make static data by simply adding values to the List and linking them to the desired columns. But I don't understand how to make it so that I could display values from my database (I work through the connection string and MySQL).
What the markup looks like
<ListView
Name="LVBuild">
<ListView.View>
<GridView>
<GridViewColumn
DisplayMemberBinding="{Binding ID}"
Header="ID" />
<GridViewColumn
DisplayMemberBinding="{Binding Title}"
Header="Title" />
<GridViewColumn
DisplayMemberBinding="{Binding Description}"
Header="Description" />
<GridViewColumn
DisplayMemberBinding="{Binding BuildData}"
Header="BuildDate">
<GridViewColumn.CellTemplate>
My model
public class BuildModel
{
public int ID { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string BuildData { get; set; }
public int Architect { get; set; }
public int Location { get; set; }
public int Teg { get; set; }
}
public class BuildManager
{
public static List<BuildModel> GetBuilds()
{
List<BuildModel> items = new List<BuildModel>();
items.Add(new BuildModel() {ID = 1, Title = "Test1", Description = "Desc1", BuildData = "12.12.2022", Architect = 1, Location = 1, Teg = 1});
items.Add(new BuildModel() {ID = 2, Title = "Test2", Description = "Desc2"});
items.Add(new BuildModel() {ID = 3, Title = "Test3"});
items.Add(new BuildModel() {ID = 4, Title = "Test4"});
return items;
}
}
How do I pass values from a model
public partial class BuildPageAdmin : Page
{
private List<BuildModel> Builds;
public BuildPageAdmin()
{
InitializeComponent();
LVBuild.ItemsSource = BuildManager.GetBuilds();
}
}
Simply use data binding: create a public property to hold the source collection and update it with data from your database. Data binding overview (WPF .NET)
If your collection is a ObservableCollection you can update it dynamically:
<Page>
<ListView ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=Page}, Path=Builds}">
</ListView>
</Page>
public partial class BuildPageAdmin : Page
{
// Create a binding source for the ListView
public ObservableCollection<BuildModel> Builds { get; }
public BuildPageAdmin()
{
InitializeComponent();
this.Builds = new ObservableCollection<BuildModel>();
this.Loaded += OnPageLoaded;
}
private void OnPageLoaded(object sender, RoutedEventArgs e)
=> UpdateBuildModels();
// Dynamically update the source collection at any time
private void UpdateBuildModels()
{
this.Builds.Clear();
// Get data from database
IEnumerable<BuldModel> newBuildModels = BuildManager.GetBuilds();
// Update source collection with new data from the database
foreach (BuildModel buildModel in newBuildModels)
{
this.Builds.Add(bulidModel);
}
}
}

How to add a column to a datagrid for a selected item in WPF?

I have a datagrid which looks like this.
I want for the user to be able to manually enter the date after clicking 'Add Interview DT' for a selected item in the 'Interview Date and time' column.
My code so far for Shortlist.xaml.cs is like this:
List<ShortlistedClient> shlclients = new List<ShortlistedClient>();
public Shortlist()
{
InitializeComponent();
DataContext = shlclients;
shlclients.Add(new ShortlistedClient("Rich", "07515118265", "rich#gmail.com", "Glasgow", "Office", "MSc", "more than 3 years", "Yes", "No"));
shlclients.Add(new ShortlistedClient("Steve", "07515118265", "steve#gmail.com", "Glasgow", "Construction", "High School", "more than 3 years", "Yes", "No"));
shlclients.Add(new ShortlistedClient("Maria", "07485999005", "mb#gmail.com", "Edinburgh", "Office", "MSc", "more than 3 years", "No", "No"));
}
// remove shortlisted client
private void RemoveShClient(object sender, RoutedEventArgs e)
{
if (dgr.Items.Count >= 1)
{
if (dgr.SelectedValue != null)
{
var items = (List<ShortlistedClient>)dgr.ItemsSource;
var item = (ShortlistedClient)dgr.SelectedValue;
dgr.ItemsSource = null;
dgr.Items.Clear();
items.Remove(item);
dgr.ItemsSource = items;
}
}
else
{
System.Windows.Forms.MessageBox.Show("No Clients Found");
}
}
So I need help with writing this method:
// method to fill in data for the date and time column
private void addInterviewDT(object sender, RoutedEventArgs e)
{
ShClient sc = dgr.SelectedItem as ShClient;
if (sc != null)
{
?
}
}
My Client and ShortlistedClient classes are defined as follows:
public partial class Client
{
public string Name { get; set; }
public string Phone { get; set; }
public string Email { get; set; }
public string Location { get; }
public string Worktype { get; }
public string Qualification { get; }
public string Workexp { get; }
public string Drlicence { get; }
public string Crconviction { get; }
public bool IDed { get; private set; }
public Client(string n, string p, string e, string l, string wt, string q, string we, string dl, string cc)
{
Name = n;
Phone = p;
Email = e;
Location = l;
Worktype = wt;
Qualification = q;
Workexp = we;
Drlicence = dl;
Crconviction = cc;
}
}
public class ShortlistedClient : Client
{
public DateTime DT { get; set; }
public bool InterestedinVac { get; private set; }
public List<ShortlistedClient> clients { get; set; } = new List<ShortlistedClient>();
public ShortlistedClient(string n, string p, string e, string l, string wt, string q, string we, string dl, string cc) : base(n, p, e, l, wt, q, we, dl, cc)
{
DT = new DateTime();
InterestedinVac = false;
}
}
And my code for the Shortlist.xaml is this:
<Window x:Class="WpfApp_Employment_Help.Shortlist"
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"
xmlns:local="clr-namespace:WpfApp_Employment_Help"
mc:Ignorable="d"
Title="Shortlist" Height="450" Width="800">
<StackPanel Margin="27,0,0,77">
<DataGrid x:Name="dgr" AutoGenerateColumns="False" ItemsSource="{Binding}" IsSynchronizedWithCurrentItem="True" CanUserAddRows="False" Height="154" Width="760">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Name}" />
<DataGridTextColumn Header="Email" Binding="{Binding Email}" />
<DataGridTextColumn Header="Phone" Binding="{Binding Phone}"/>
<DataGridTextColumn Header="Location" Binding="{Binding Location}"/>
<DataGridTextColumn Header="Worktype" Binding="{Binding Worktype}"/>
<DataGridTextColumn Header="Qualification" Binding="{Binding Qualification}"/>
<DataGridTextColumn Header="Workexp" Binding="{Binding Worktype}"/>
<DataGridTextColumn Header="Driving licence" Binding="{Binding Drlicence}"/>
<DataGridTextColumn Header="Criminal conviction" Binding="{Binding Crconviction}"/>
<DataGridTextColumn Header="Interview Date and time" Binding="{Binding DT}"/>
</DataGrid.Columns>
</DataGrid>
<Button Content="Add Interview DT" Width="128" FontWeight="Bold" Height="28"/>
<TextBox TextWrapping="Wrap" Text="TextBox" Width="120" Height="46"/>
<Button x:Name="BtnRemoveShlClient" Content="Remove Shortlisted Client" FontWeight="Bold" Height="33" Width="221" Click="RemoveShClient"/>
</StackPanel>
</Window>
Additionally, how can I show my Interview date and time column values as empty instead of '1/1/0001 12:00:00 AM'?
thank you, I'm new to C# and wpf.
First of all ShortlistedClient must implement INotifyPropertyChanged for you to be able to dynamically set one of its properties and have the UI updated automatically:
public class ShortlistedClient : Client, INotifyPropertyChanged
{
private DateTime _dt;
public DateTime DT
{
get { return _dt; }
set { _dt = value; NotifyPropertyChanged(); }
}
public bool InterestedinVac { get; private set; }
public List<ShortlistedClient> clients { get; set; } = new List<ShortlistedClient>();
public ShortlistedClient(string n, string p, string e, string l, string wt, string q, string we, string dl, string cc) : base(n, p, e, l, wt, q, we, dl, cc)
{
DT = new DateTime();
InterestedinVac = false;
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
You can then parse the value of the TextBox and try to set the property:
private void addInterviewDT(object sender, RoutedEventArgs e)
{
ShortlistedClient sc = dgr.SelectedItem as ShortlistedClient;
if (sc != null && DateTime.TryParse(textBox.Text, out DateTime value))
{
sc.DT = value;
}
}
textBox is the name of the TextBox control:
<TextBox x:Name="textBox" TextWrapping="Wrap" Text="TextBox" Width="120" Height="46"/>
additionally, how can I show my Interview date and time column values as empty instead of '1/1/0001 12:00:00 AM'?
Change the type of the DT property to Nullable<DateTime>.

Create Static Header with Dynamic Empty Editable Rows in WPF

Anyone have the idea how to create a dynamic row with header table in WPF program.
I am able to create the dynamic row with header, but unfortunately the rows unable to edit. (Attached Screenshot)
xaml (source code)
<DataGrid Name = "dataGrid" CanUserAddRows="True" AutoGenerateColumns = "False" Grid.Column="0" Grid.Row="2">
<DataGrid.Columns>
<DataGridTextColumn Header = "NUMBER " Binding = "{Binding Path=ID}" />
<DataGridTextColumn Header = "STAGE ID " Binding = "{Binding Path=StageID}" />
<DataGridTextColumn Header = "STAGE DESCRIPTION " Binding = "{Binding Path=StageDescription}"/>
</DataGrid.Columns>
</DataGrid>
cs (source code)
for (int i = 1; i <= 4; ++i)
{
dataGrid.Items.Add(new Stage());
}
public class Stage
{
public string ID { get; set; }
public string StageID { get; set; }
public string StageDescription { get; set; }
}
Table
private readonly ObservableCollection<Stage> stages
= new ObservableCollection<Stage>();
public СonstructorWindow()
{
InitializeComponent();
dataGrid.ItemsSource = stages;
}
void SomeMethod()
{
for (int i = 0; i < 4; i++)
{
srages.Add(new Stage());
}
}

How can I set a selection in a DataGridComboBoxColumn?

How can I set a DataGridComboBoxColumn item selection programmatically?
I want to populate my list with data, and the comboboxitem should set the selected item from the list.
But I dont find any way to achieve that.
In this example the selection should be "Forward"
XAML:
<DataGrid ItemsSource="{Binding }" x:Name="dgSFD" AlternatingRowBackground="BlanchedAlmond" SelectionChanged="dgSFD_SelectionChanged" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=sID}" Header="Step ID"/>
<DataGridComboBoxColumn x:Name="cbServo" Header="Servo" SelectedItemBinding="{Binding Servo, Mode =TwoWay}" SelectedValuePath="sFunctionName ,Mode=TwoWay" DisplayMemberPath="sFunctionName"/>
</DataGrid>
Class
public class Step
{
public string sID { get; set; }
public Servo serServo { get; set; }
}
public class Servo
{
public string sFunction { get; set; }
public string sServo { get; set; }
}
C#
public static List<Step> listStep { get; set; }
public static List<Servo> listServo { get; set; }
public MainWindow()
{
InitializeComponent();
}
public void loadList()
{
dgSFD.ItemsSource = listStep;
cbServo.ItemsSource = listServo;
}
public void testfill()
{
Servo newServo = new Servo();
newServo.sFunctionName = "Forward";
newServo.sServo = "Left";
listServo.Add(newServo);
Step newStep = new Step();
newStep.serServo = newServo;
newStep.sID = "1";
listStep.Add(newStep);
}
Bind the SelectedItemBinding property to the serServo property of the Step object:
<DataGridComboBoxColumn x:Name="cbServo" Header="Servo" SelectedItemBinding="{Binding serServo, Mode=TwoWay}" DisplayMemberPath="sFunction"/>

How to: Fill a DataGrid.DataContext with information from txt files (C#, WPF)

How to: Fill a DataGrid.DataContext with information from txt files (C#, WPF)
I am trying to fill my DataGrid with information I get from some txt files. There is a folder called "CONTACTS" and there are some (5) files in. These files are configurated this way:
Content of John Doe.txt (without list symbols):
John Doe Corp.
Mr.
Doe
John
XAML:
<DataGrid AutoGenerateColumns="False" CanUserResizeRows="False" DockPanel.Dock="Bottom" ItemsSource="{Binding CollectionofDetails}" Name="dataGrid_Content">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding CorporationName}" Header="Firma" />
<DataGridTextColumn Binding="{Binding Prefix}" Header="Anrede" />
<DataGridTextColumn Binding="{Binding FirstName}" Header="Nachname" />
<DataGridTextColumn Binding="{Binding LastName}" Header="Vorname" />
</DataGrid.Columns>
</DataGrid>
C#:
public class Details
{
public string CorporationName { get; set; }
public string Prefix { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public ObservableCollection<Details> _CollectionofDetails = new ObservableCollection<Details>();
public ObservableCollection<Details> CollectionofDetails
{
get { return _CollectionofDetails; }
set { _CollectionofDetails = value; }
}
public void SetItemsToDataContext()
{
foreach (string Datei in Directory.GetFiles(#"C:\Users\schwarz\Desktop\Cusposes_2014-05-20_0827\ISAPO\ISAPO Cusposes\Business Contacts\Contacts", "*.txt"))
{
StreamReader reader = new StreamReader(Datei);
int i = 0;
string line = reader.ReadToEnd().Replace("\n", "");
string[] t = line.Split('\r');
Details d = new Details();
d.CorporationName = t[i];
d.Prefix = t[i + 1];
d.FirstName = t[i + 2];
d.LastName = t[i + 3];
CollectionofDetails.Add(d);
reader.Close();
}
}
Unfortunately, I do have the following problems:
I do not know how to load THE CONTENT of each file (for all files).
I do not know how to fill my DataGrid with this Information.
--> Solution by Dhaval Patel (see below).
You can use the below mentioned code
Your Xaml Code looks like
<DataGrid AutoGenerateColumns="False" CanUserResizeRows="False" DockPanel.Dock="Bottom" ItemsSource="{Binding CollectionofDetails}" Name="dataGrid_Content">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding CorporationName}" Header="Firma" />
<DataGridTextColumn Binding="{Binding Prefix}" Header="Anrede" />
<DataGridTextColumn Binding="{Binding FirstName}" Header="Nachname" />
<DataGridTextColumn Binding="{Binding LastName}" Header="Vorname" />
</DataGrid.Columns>
</DataGrid>
<Button Command="{Binding MyCommand}" Width="100" Margin="346,230,346,-189">RunMyCommand</Button>
Your ViewModel code look like
private ObservableCollection<Details> _CollectionofDetails=new ObservableCollection<Details>();
public ObservableCollection<Details> CollectionofDetails
{
get { return _CollectionofDetails; }
set { _CollectionofDetails = value; RaisePropertyChanged("CollectionofDetails"); }
}
private RelayCommand _MyCommand;
public RelayCommand MyCommand
{
get { return _MyCommand??(_MyCommand=new RelayCommand(Methodcall)); }
set { _MyCommand = value; }
}
void Methodcall()
{
foreach (string Datei in Directory.GetFiles(#"C:\textfile", "*.txt"))
{
StreamReader reader = new StreamReader(Datei);
int i=0;
string line = reader.ReadToEnd().Replace("\n","");
string[] t = line.Split('\r');
Details d = new Details();
d.CorporationName = t[i];
d.Prefix = t[i + 1];
d.FirstName = t[i + 2];
d.LastName = t[i + 3];
CollectionofDetails.Add(d);
reader.Close();
}
}
public class Details
{
public string CorporationName { get; set; }
public string Prefix { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
output should look like
This is a problem that you have to break into pieces. I would recommend that you define a class suitable for your data, like
public class Person {
public string FullName {get; set;}
public string FirstName {get; set;}
public string LastName {get; set;}
public string Title {get; set;}
}
and in your viewmodel class you have a variable PersonList of type List<Person>.
Then your have to write a method, something like
private void PopulatePersonData(){
// Here you put all the logic reading the .txt files creating a person for each file
// and adding the person to the PersonList.
}
which you then call in the constructor of the viewmodel.
Finally you bind the ItemsSource of your DataGrid to the PersonList. That should do it.
Maybe you should really read what is in your txt files.
By using for example a Reader :
private void SetItemsToDataContext()
{
foreach (String Datei in Directory.GetFiles(#"C:\Contacts", "*.txt"))
{
String[] linesRead = File.ReadAllLines(Datei);
if (linesRead.Length != 4)
{
continue;
}
Contact contactRead = new Contact();
contactRead.Company = linesRead[0];
contactRead.Gender = linesRead[1];
contactRead.Name = linesRead[2];
contactRead.FirstName = linesRead[3];
dataGrid_Content.Items.Add(contactRead);
}
}
public class Contact
{
public String Company { get; set; }
public String Gender { get; set; }
public String Name { get; set; }
public String FirstName { get; set; }
}

Categories

Resources