i am changing the value of a column cell, but whenever i hit enter, it display the old value. what can i do to make it give me the new value? Here's my code
private void DataGrid1_CellEditEnding_1(object sender, DataGridCellEditEndingEventArgs e)
{
// Now you have the cell you are dealing with, so you can do what ever you want from here
var currentRowIndex = DataGrid1.Items.IndexOf(DataGrid1.CurrentItem);
int i = DataGrid1.SelectedIndex;
DATA[currentRowIndex].TotalPrice1 = DATA[currentRowIndex].Quantity * DATA[currentRowIndex].ItemPrice;
MessageBox.Show(DATA[currentRowIndex].TotalPrice1.ToString());
DataGrid1.ItemsSource = null;
DataGrid1.ItemsSource = DATA;
}
and heres my xaml
<DataGrid RowEditEnding="DataGrid1_RowEditEnding_1" CellEditEnding="DataGrid1_CellEditEnding_1" TargetUpdated="DataGrid1_TargetUpdated" AutoGenerateColumns="False" CanUserAddRows="False" CanUserDeleteRows="True" EnableColumnVirtualization="False" EnableRowVirtualization="False" IsSynchronizedWithCurrentItem="True" SelectedItem="{Binding SelectedItem}" Grid.Row="3" Grid.ColumnSpan="2" Name="DataGrid1" ItemsSource="{Binding DATA,NotifyOnSourceUpdated=True, Mode=TwoWay, IsAsync=True,UpdateSourceTrigger=PropertyChanged}" Margin="10,10,10,10" PreviewKeyDown="DataGrid1_PreviewKeyDown" SourceUpdated="DataGrid1_SourceUpdated" TextInput="DataGrid1_TextInput" >
<DataGrid.Columns>
<DataGridTextColumn Header="Item Name" IsReadOnly="True" Binding="{Binding Path=ItemName}" Width="*"></DataGridTextColumn>
<DataGridTextColumn Header="Item Price" IsReadOnly="True" Binding="{Binding Path=ItemPrice}" Width="*"></DataGridTextColumn>
<DataGridTextColumn x:Name="QuantityColumn" Header="Quantity" IsReadOnly="False" Binding="{Binding Path=Quantity, Mode=TwoWay}" Width="*"></DataGridTextColumn>
<DataGridTextColumn Header="Total Price" IsReadOnly="True" Binding="{Binding Path=TotalPrice1, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="*"></DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
Related
im trying to select multiple rows/items from a datagrid
<DataGrid IsReadOnly="True" SelectionMode="Extended" SelectionUnit="FullRow" AutoGenerateColumns="False" ItemsSource="{Binding Source={StaticResource ClientiVS}}" SelectedItem="{Binding Path=ClienteSelezionato}" RowHeaderWidth="0" EnableColumnVirtualization="False" CanUserReorderColumns="False" EnableRowVirtualization="False" CanUserAddRows="false" ColumnWidth="*" FontFamily="Agency FB" FontSize="22" Name="DataGrid1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" SelectionChanged="DataGrid1_SelectionChanged" Grid.Row="1" Margin="30,10,30,30">
XAML DATAGRID CODE
<DataGrid.Columns>
<DataGridTextColumn Width="100" FontFamily="Agency FB" FontSize="20" Header="Nome" Binding="{Binding Nome}" ></DataGridTextColumn>
<DataGridTextColumn Width="100" FontFamily="Agency FB" FontSize="20" Header="Cognome" Binding="{Binding Cognome}" ></DataGridTextColumn>
<DataGridTextColumn Width="150" FontFamily="Agency FB" FontSize="20" Header="Indirizzo" Binding="{Binding Indirizzo}"></DataGridTextColumn>
<DataGridTextColumn Width="150" FontFamily="Agency FB" FontSize="20" Header="Telefono" Binding="{Binding NumeroTelefono}"></DataGridTextColumn>
<DataGridTextColumn Width="1*" FontFamily="Agency FB" FontSize="20" Header="Email" Binding="{Binding Email}"></DataGridTextColumn>
<DataGridCheckBoxColumn Header="Selezionato" Binding="{Binding ClienteSelezionato}"/>
</DataGrid.Columns>
</DataGrid>
DATAGRID SELECTIONCHANGED EVENT CODE:
public Cliente ClienteSelezionato { get; set; }
private ObservableCollection<Cliente> _ListaClientiSelezionati;
public ObservableCollection<Cliente> ListaClientiSelezionati { get { return _ListaClientiSelezionati; } set { _ListaClientiSelezionati = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("ListaClientiSelezionati")); } }
private void DataGrid1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (ClienteSelezionato != null )
{
ListaClientiSelezionati.Add(ClienteSelezionato);
}
}
The problem is that: if i select two times the same Row from the DataGrid("ClienteSelezionato") it will obviously insert into the list the same item twice. How can i fix it ?
I just want to implement the control that tells me if an item is already contained in the list ("ListaClientiSelezionati")
Thanks!
I am trying to make a page in an app which will use a datagrid to allow users to view and edit data from a SQL Server database. I would like changes to be saved back to the database immediately after they are made by the user.
I have been trying the CellEditEnding event with SqlCommandBuilder to update the database as edits are made; but after every change it shows 0 updates and nothing is saved.
I can see that the changes in the datagrid are reflected in the datatable, and there is an UpdateCommand generated, but no change is made to the database.
Is there something here that I have missed?
Alternatively is there a way to manually create an update command based on the data in the edited row?
I am new to C# and WPF so any help is appreciated.
EDIT
I have tried using a manually generated UpdateCommand and it still does nothing, so I believe the problem occurs around adapter.Update(dt);. For some reason the data is not saving to the database from the datatable.
Code:
public partial class pgMain : Page
{
private SqlDataAdapter adapter;
private DataTable dt;
public pgMain()
{
InitializeComponent();
}
private void Page_Initialized(object sender, EventArgs e)
{
try
{
string connectionString = ConfigurationManager.ConnectionStrings["connPlanDB"].ConnectionString;
SqlConnection cnn = new SqlConnection(connectionString);
cnn.Open();
adapter = new SqlDataAdapter("SELECT * FROM [AdvProdApp].[dbo].[Orders] WHERE Position > 0 AND Hidden = 0 ORDER BY Linje, Position", cnn);
dt = new DataTable();
adapter.Fill(dt);
ICollectionView indata = CollectionViewSource.GetDefaultView(dt.DefaultView);
indata.GroupDescriptions.Add(new PropertyGroupDescription("Linje"));
Tbl_Plan.DataContext = dt;
cnn.Close();
}
catch (Exception ex)
{
MessageBox.Show("Error: Cannot connect to database");
}
}
private void Tbl_Plan_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
{
try
{
string connectionString = ConfigurationManager.ConnectionStrings["connPlanDB"].ConnectionString;
SqlConnection cnn = new SqlConnection(connectionString);
cnn.Open();
SqlCommandBuilder builder = new SqlCommandBuilder(adapter);
adapter.UpdateCommand = builder.GetUpdateCommand();
int u = adapter.Update(dt);
dt.AcceptChanges();
MessageBox.Show(u.ToString());
cnn.Close();
}
catch (Exception ex)
{
MessageBox.Show("Error: Cannot connect to database");
}
}
}
XAML
<DataGrid x:Name="Tbl_Plan" Margin="100,30,50,100" AlternatingRowBackground="Beige" AlternationCount="2" RenderTransformOrigin="0.5,0.5"
CanUserSortColumns="False" VerticalAlignment="Top" Height="900" VerticalScrollBarVisibility="Visible" CanUserDeleteRows="False"
AutoGenerateColumns="False" ItemsSource="{Binding}" CellEditEnding="Tbl_Plan_CellEditEnding">
<DataGrid.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<StackPanel>
<StackPanel Orientation="Horizontal" Background="Black">
<TextBlock Text=" Linje " FontWeight="Bold" FontSize="16" Foreground="White" />
<TextBlock Text="{Binding Name}" FontWeight="Bold" FontSize="16" Foreground="White" />
</StackPanel>
<ItemsPresenter />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</DataGrid.GroupStyle>
<DataGrid.Columns>
<DataGridTextColumn Header="Plandate" Binding="{Binding Plandate}" IsReadOnly="True" />
<DataGridTextColumn Header="Nr" Binding="{Binding Nr}" IsReadOnly="True" />
<DataGridTextColumn Header="Ordernr" Binding="{Binding Ordernr}" IsReadOnly="True" />
<DataGridTextColumn Header="Ursprungsnr" Binding="{Binding Ursprungsnr}" IsReadOnly="True" />
<DataGridTextColumn Header="Description" Binding="{Binding Description}" IsReadOnly="True" />
<DataGridTextColumn Header="Kundnr" Binding="{Binding Kundnr}" IsReadOnly="True" />
<DataGridTextColumn Header="Kundnamn" Binding="{Binding Kundnamn}" IsReadOnly="True" />
<DataGridTextColumn Header="Duedate" Binding="{Binding Duedate}" IsReadOnly="True" />
<DataGridTextColumn Header="Antal" Binding="{Binding Antal}" IsReadOnly="True" />
<DataGridTextColumn Header="Optisk_Ref" Binding="{Binding Optisk_Ref}" IsReadOnly="True" />
<DataGridTextColumn Header="Gen Info" Binding="{Binding sign_Geninfo, NotifyOnTargetUpdated=True, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsReadOnly="False" />
<DataGridTextColumn Header="Optisk Start" Binding="{Binding sign_Optiskstart, NotifyOnTargetUpdated=True, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsReadOnly="False" />
<DataGridTextColumn Header="Optisk Slut" Binding="{Binding sign_Optiskslut, NotifyOnTargetUpdated=True, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsReadOnly="False" />
<DataGridTextColumn Header="Ingen Optisk Ref" Binding="{Binding sign_Ingenoptisk, NotifyOnTargetUpdated=True, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsReadOnly="False" />
<DataGridTextColumn Header="Efterblandad" Binding="{Binding Efterblandad, NotifyOnTargetUpdated=True, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsReadOnly="False" />
<DataGridTextColumn Header="Ă„ndringar" Binding="{Binding Ă„ndringar, NotifyOnTargetUpdated=True, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsReadOnly="False" />
<DataGridTextColumn Header="Kgh" Binding="{Binding Kgh, NotifyOnTargetUpdated=True, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsReadOnly="False" />
<DataGridTextColumn Header="Notes" Binding="{Binding Notes, NotifyOnTargetUpdated=True, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsReadOnly="False" />
</DataGrid.Columns>
</DataGrid>
Got a list of objects which is currently being displayed via a datagrid. What I need to do is when a user double clicks on a specified row it opens up another window which is a model showing the data associated with the object of the row that is currently selected. I can't figure out how to a) detect when the user double clicks and b) how to know which row the user double clicked on.
The XAML:
<DataGrid x:Name="BlueprintsDataGrid" Grid.Row="0" IsReadOnly="True"
ItemsSource="{Binding Path=Game.Blueprints, ElementName=uc}"
AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Width="80*" Binding="{Binding Name}"/>
<DataGridTextColumn Header="ME" Width="30*" Binding="{Binding MaterialEfficiency}"
HeaderStyle="{StaticResource HeaderRightJustify}"
CellStyle="{StaticResource ColumnRight}"/>
<DataGridCheckBoxColumn Header="BPO" Width="30*" Binding="{Binding IsOrginial}"
HeaderStyle="{StaticResource HeaderRightJustify}"/>
</DataGrid.Columns>
</DataGrid>
You could do something like the following:
<DataGrid x:Name="BlueprintsDataGrid" Grid.Row="0" IsReadOnly="True"
ItemsSource="{Binding Path=Game.Blueprints, ElementName=uc}"
SelectedItem="{Binding CurrentSelection}"
AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Width="80*" Binding="{Binding Name}"/>
<DataGridTextColumn Header="ME" Width="30*" Binding="{Binding MaterialEfficiency}"
HeaderStyle="{StaticResource HeaderRightJustify}"
CellStyle="{StaticResource ColumnRight}"/>
<DataGridCheckBoxColumn Header="BPO" Width="30*" Binding="{Binding IsOrginial}"
HeaderStyle="{StaticResource HeaderRightJustify}"/>
</DataGrid.Columns>
</DataGrid>
Note: CurrentSelection must exist in your ViewModel-class. This property has to implement the INotifyPropertyChanged interface and must be the type of object your ItemsSource is holding!
For recognizing the mouse double click you can extend the above xaml to something like
<DataGrid x:Name="BlueprintsDataGrid" Grid.Row="0" IsReadOnly="True"
ItemsSource="{Binding Path=Game.Blueprints, ElementName=uc}"
SelectedItem="{Binding CurrentSelection}"
AutoGenerateColumns="False">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<i:InvokeCommandAction Command="{Binding DoubleClickedCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Width="80*" Binding="{Binding Name}"/>
<DataGridTextColumn Header="ME" Width="30*" Binding="{Binding MaterialEfficiency}"
HeaderStyle="{StaticResource HeaderRightJustify}"
CellStyle="{StaticResource ColumnRight}"/>
<DataGridCheckBoxColumn Header="BPO" Width="30*" Binding="{Binding IsOrginial}"
HeaderStyle="{StaticResource HeaderRightJustify}"/>
</DataGrid.Columns>
</DataGrid>
Note: You therefore need a property DoubleClickedCommand of the type ICommand in your ViewModel. There you can check for your CurrentSelection.
public ICommand DoubleClickedCommand { get; set; }
In your ViewModel constructor:
DoubleClickedCommand = new RelayCommand(DoubleClick);
And the method itself:
private void DoubleClick()
{
if(CurrentSelection == null) { return; }
// Do stuff in here
}
You could handle the MouseDoubleClick event and cast the DataContext of the source of the event:
private void OnMouseDoubleClick(object sender, MouseButtonEventArgs e)
{
var fe = e.OriginalSource as FrameworkElement;
if (fe != null)
{
var blueprint = fe.DataContext as BluePrint;
if (blueprint != null)
{
//open window...
}
}
}
XAML:
<DataGrid x:Name="BlueprintsDataGrid" Grid.Row="0" IsReadOnly="True"
ItemsSource="{Binding Path=Game.Blueprints, ElementName=uc}"
AutoGenerateColumns="False"
MouseDoubleClick="Dgm_MouseDoubleClick">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Width="80*" Binding="{Binding Name}"/>
<DataGridTextColumn Header="ME" Width="30*" Binding="{Binding MaterialEfficiency}"
HeaderStyle="{StaticResource HeaderRightJustify}"
CellStyle="{StaticResource ColumnRight}"/>
<DataGridCheckBoxColumn Header="BPO" Width="30*" Binding="{Binding IsOrginial}"
HeaderStyle="{StaticResource HeaderRightJustify}"/>
</DataGrid.Columns>
</DataGrid>
Change BluePrint to whatever the name of your class is.
I work with wpf, and I have a datagrid which lists all my clients from the table client.
<DataGrid x:Name="liste_clients" AutoGenerateColumns="False" x:Uid="liste_clients" Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="2" Grid.RowSpan="4" SelectionChanged="client_select">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=nom}" IsReadOnly="True" Header="NOM" Width="*"></DataGridTextColumn>
<DataGridTextColumn Binding="{Binding Path=prenom}" IsReadOnly="True" Header="PRENOM" Width="*">
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
this my function
private void client_select(object sender, SelectionChangedEventArgs e)
{
linqDataContext dataContext = new linqDataContext();
client client = (client)liste_clients.SelectedItem;
int id = client.id;
MessageBox.Show(id.ToString());
}
I just want to click on a row, and get the corresponding object in my function.
I don't know how to do it.
And I still have a client referenced null.
How can I get all of the checked rows in WPF datagrid using C# code behind?
I'm trying a batch deletion with these codes but I need to get all checked rows first.
Here is my datagrid
<DataGrid x:Name="DiseaseSymptomsDataGrid" Grid.Row="1"
SelectionMode="Extended"
GridLinesVisibility="All"
CanUserSortColumns="False"
CanUserAddRows="False"
HeadersVisibility="Column"
AutoGenerateColumns="False"
PreviewMouseLeftButtonUp="DiseaseSymptomsDataGrid_OnPreviewMouseLeftButtonUp"
>
<DataGrid.Columns>
<DataGridTextColumn x:Name="IdColumn" Binding="{Binding Id}" Header="Id" Visibility="Collapsed" IsReadOnly="True"/>
<DataGridTextColumn x:Name="DiseaseIdColumn" Binding="{Binding DiseaseId}" Header="DiseaseId" Visibility="Collapsed" IsReadOnly="True"/>
<DataGridTextColumn x:Name="DiseaseNameColumn" Binding="{Binding DiseaseName}" Header="Disease" Visibility="Collapsed" IsReadOnly="True"/>
<DataGridTextColumn x:Name="SymptomIdColumn" Binding="{Binding SymptomId}" Header="SymptomId" Visibility="Collapsed" IsReadOnly="True"/>
<DataGridTextColumn x:Name="SymptomNameColumn" Binding="{Binding SymptomName}" Header="Symptom" IsReadOnly="True"/>
<DataGridTextColumn x:Name="DescriptionColumn" Binding="{Binding SymptomDescription}" Header="Description" Width="425" IsReadOnly="True"/>
<DataGridCheckBoxColumn x:Name="StatusIdColumn" Header="Delete" IsReadOnly="False"/>
</DataGrid.Columns>
</DataGrid>
Here is my attempted code behind
public List<DiseaseSymptomParams> GetSelectedDiseaseSymptom()
{
var entiParams = new DiseaseSymptomParams();
var selectedDiseases = new List<DiseaseSymptomParams>();
try
{
// this will only get the highlighted row, not ALL the checked rows
foreach (DiseaseSymptom itemSelected in DiseaseSymptomsDataGrid.SelectedItems)
{
entiParams.Id = DefaultValue.GetInt(itemSelected.Id);
selectedDiseases.Add(entiParams);
}
}
catch (Exception)
{
}
return selectedDiseases;
}
Here is what you could do:
foreach (DiseaseSymptom item in DiseaseSymptomsDataGrid.ItemsSource)
{
if (((CheckBox)StatusIdColumn.GetCellContent(item)).IsChecked == true)
{
selectedDiseases.Add(item);
}
}
Not MVVM-compliant but pragmatic.