Get Cell value from DataGrid - wpf

I am having some troubles with my datagrid ( WPF ) and since I am already a beginner I am not so very good in it.
Maybe, someone can help me out here.
I already have the row-index and column index and what I want to have now is the value from this cell.
But I do not know how to get it.
Here is my code:
var row = datagrid.Items.IndexOf(datagrid.CurrentItem);
var column = datagrid.SelectedCells[0].Column.DisplayIndex;
How is it possible now to retrieve with these two indexes now my cell vlaue.
I must solve it somehow via the indexes!
Thank you very much for your help!

Here is the sample code that gets cell value from datagrid in WPF on button click
In your MainWindow.cs
private ObservableCollection<ItemDG> _it = new ObservableCollection<ItemDG>();
public MainWindow()
{
InitializeComponent();
_it.Add(new ItemDG() { Amount = 10 });
_it.Add(new ItemDG() { Amount = 20 });
_it.Add(new ItemDG() { Amount = 30 });
dataGrid1.ItemsSource = _it;
}
private void button1_Click_1(object sender, RoutedEventArgs e)
{
TextBlock x = dataGrid1.Columns[0].GetCellContent(dataGrid1.Items[2]) as TextBlock;
if (x != null)
MessageBox.Show(x.Text);
}
}
public class ItemDG
{
public int Amount { get; set; }
}
and in your MainWindow.xaml
<DataGrid AutoGenerateColumns="False" Name="datagrid1"/>
<Button Content="Button" Name="button1" Click="button1_Click_1" />

Related

WPF ComboBox bad blank value

I have a WPF ComboBox that binds to a set of data. I do not have permissions to modify the control directly, nor can I change the data.
I'm returned 1 item in my ComboBox, but there are actually 2 rows; the blank row and my expected value. Both appear to have an index value of 0. I don't want to see this blank row, just my expected data in the ComboBox auto-selected. I have looked through everyone's related posts in here, but none of the solutions have worked for my case. I have been programming for a long time, but still fairly new to WPF. Thanks for the help.
XAML
<MyComboBox Name="myTemplate5" MyLookup="Lookup" MyFilter="att_idn=-37" MyData="Detail" MyName="comp_tmpl_idn_srt" ModCde="31" MyEmptyValue="0" ToolTip="Have a nice day" Margin="0,2.5,30,2.5" MinWidth="120" Grid.Column="1" SelectionChanged="myTemplate5_SelectionChanged" />
C#
private void myTemplate1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
MyComboBox work = sender as MyComboBox;
if (work != null && work.HasSelectionChanged(e))
{
int compTmplId = int.Parse(work.SelectedValue.ToString());
if (!_wpfIsDumb && !ChangeComponent(compTmplId))
{
_wpfIsDumb = true;
work.SelectedItem = e.RemovedItems[0];
_wpfIsDumb = false;
}
}
}
public bool HasSelectionChanged(SelectionChangedEventArgs e)
{
if (e.RemovedItems.Count > 0 && e.AddedItems.Count > 0)
return true;
else
return false;
}
I found the solution. The selected index did not work. The problem was with the data. I was getting a NULL value passed to the box. Once I stripped out the NULL return from SQL, then it worked as expected.
You can achieved this by setting the SelectedIndex to 0.
XAML:
<ComboBox Name="myCB"
SelectedIndex="0"
MaxWidth="200" MaxHeight="25" />
Code-behind:
namespace nsComboBox
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
myCB.Items.Add("Item 1");
myCB.Items.Add("Item 2");
myCB.Items.Add("Item 3");
myCB.SelectedIndex = 0;
}
}
}

how to add row in datagrid dynamically

I am using WPF application
in this form have one gridview and one button
i am using the ObservableCollection have Generic and one class code like this
public partial class MainWindow : Window
{
public ObservableCollection<gm> data1 = new ObservableCollection<gm>();
public MainWindow()
{
InitializeComponent();
}
// public ObservableCollection<gm> data { get { return data1; } }
private void button1_Click_1(object sender, RoutedEventArgs e)
{
data1.Add(new gm() { no = 2, name = "vipul" });
dataGrid1.ItemsSource = data1.ToArray();
}
}
public class gm
{
public int no { get; set; }
public string name { get; set; }
}
}
when i am execute above code it add blank row in datagrid
please give me solution of this problem
i want to know how to add row in datagird run time.
thanks in advance
set autogeneratecolumns to true and just set data1 as itemssource
xaml
<DataGrid x:Name="dataGrid1" AutoGenerateColumns="True" />
EDIT: to get the power of WPF look into DataBinding/MVVM
XAML is like this:
<DataGrid ItemsSource="{Binding}" />
code behind is this:
public MainWindow()
{
InitializeComponent();
DataContext = data1;
}
and remove this line:
dataGrid1.ItemsSource = data1.ToArray();
data1.Add(new gm { no = 2, name = "vipul" }); // Remore ellipsis around gm.
In XAML just check the following that
You have DataSource of your datagrid to {Binding Path="data1"}
DataColumn of no have binding to {Binding Path="no"}
DataColumn of name have binding path to {Binding Path="name"}

Silverlight - DataGrid in Scrollviewer, Column.Width="*" makes datagrid take several screen-widths

When I have the following setup, the last column having a width of * causes the datagrid to create huge horizontal scrollbars (extends grid to several widths of the screen). I'm not really sure why this is, but I really need a way to avoid that. I don't want to have to "simulate" column's with * lengths.
edit: Apparently I'm not the only one who noticed this.
http://connect.microsoft.com/VisualStudio/feedback/details/559644/silverlight-4-datagrid-star-column-width
Xaml:
<ScrollViewer Padding="0" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" >
<sdk:DataGrid AutoGenerateColumns="False" x:Name="dg"/>
</ScrollViewer>
Code:
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
dg.Columns.Add(new DataGridTextColumn { Binding = new Binding("A"), Header = "A" });
dg.Columns.Add(new DataGridTextColumn { Binding = new Binding("B"), Header = "B" });
dg.Columns.Add(new DataGridTextColumn { Binding = new Binding("C"), Header = "C" });
dg.Columns[2].Width = new DataGridLength(1, DataGridLengthUnitType.Star);
dg.ItemsSource = new[]
{
new I { A = "SAF", B = "SAF", C = "SAF" },
new I { A = "SAF", B = "SAF", C = "SAF" },
new I { A = "SAF", B = "SAF", C = "SAF" }
};
}
public class I
{
public string A { get; set; }
public string B { get; set; }
public string C { get; set; }
}
you need to put a maxwidth on the scrollviewer? otherwise width is defaulted to auto and maxwidth is infinity
If you remove
dg.Columns[2].Width = new DataGridLength(1, DataGridLengthUnitType.Star);
the problem should go away. Can I ask why you want the last column to take the rest of the space? The column actually knows to resize itself properly to fit its cell size and column header size.
Also, if you don't specify the column's width, then you don't really need a scrollviewer to scroll and see all the columns. The datagrid has a scrollviewer built in and when there are columns out of the screen the horizontal scrollbar will apear.
I hope this helps. :)

WpfDatagrid Collectionviewsource clear

I am using wpftoolkit datagrid control which was binding using collectionviewsource for records grouping. Whenever user trying to clear the form i need to clear the datagrid also.
I tried to set datagrid itemsource to null but it works fine for clear functionality .if user trying to add any records to datagrid it's not loading.
So could any one please provide me a solution to clear the datagrid.
Thanks In Advance.
I use ObservableCollection for this type of situations.
Example:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.items = new ObservableCollection<Item>(
Enumerable.Range(0, 10).Select(i => new Item {Id = i, Title = "str " + i}));
this.viewSource = new CollectionViewSource() { Source = this.items };
dataGrid1.ItemsSource = this.viewSource.View;
}
private ObservableCollection<Item> items;
private CollectionViewSource viewSource;
private void Button_Click(object sender, RoutedEventArgs e)
{
items.Clear();
//or
//((ObservableCollection<Item>)viewSource.Source).Clear();
}
public class Item
{
public int Id { get; set; }
public string Title { get; set; }
}
}
Xaml:
<Button HorizontalAlignment="Center" Content="Clear" Click="Button_Click"/>
<DataGrid AutoGenerateColumns="True" Name="dataGrid1" />

WPf ListView : Save reorderd column order

For a WPF project in need to save the width and the column order of a ListView because these are things the user can change. I guess it is no problem getting the current width but the current position seems to be a bit difficult.
In WinForms there was something like index and displayIndex but I don't see it in WPF.
How is it done?
BTW : Serializing the whole control is not an option.
Edit:
I found some samples using the listView.columns property. But I don't have such a property in my listView
My XAML code is like this:
<ListView>
<ListView.View>
<GridView>
<GridViewColumn>
....
I managed to do that using the Move(…) method of the GridView's Columns collection
If you have the new order stored somehow, you could try:
((GridView)myListView.View).Columns.Move(originalIndex, newIndex);
Edit: This is NOT XAML, but code you should put in the .xaml.cs file
The Columns are always in the same oder that the gridView.Columns Collection is. You can hook into the gridView.CollectionChanged event to react to changes, see also WPF Listview : Column reorder event?
I am using a Behavior to do this. There is a dependency property on the Behavior that is bound to my DataContext. You need a reference to System.Windows.Interactivityto use interactivity.
On my DataContext there is an ObservableCollection of ColumnInfo that I store in my configuration on application exit:
public class ColumnInfo
{
public string HeaderName { get; set; }
public int Width { get; set; }
public int Index { get; set; }
}
In your control add the namespace
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
And the ListView is something like
<ListView ItemsSource="{Binding SomeCollection}">
<ListView.View>
<GridView>
<i:Interaction.Behaviors>
<b:GridViewColumnBehavior Columns="{Binding Columns}" />
</i:Interaction.Behaviors>
</GridView>
</ListView.View>
</ListView>
The Behavior I'm using (parts of it)
public class GridViewColumnBehavior : Behavior<GridView>
{
public ObservableCollection<ColumnInfo> Columns
{
get { return (ObservableCollection<ColumnInfo>)GetValue(ColumnsProperty); }
set { SetValue(ColumnsProperty, value); }
}
public static readonly DependencyProperty ColumnsProperty =
DependencyProperty.Register("Columns", typeof(ObservableCollection<ColumnInfo>), typeof(GridViewColumnBehavior), new PropertyMetadata(null, new PropertyChangedCallback(Columns_Changed)));
private static void Columns_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var b = d as GridViewColumnBehavior;
if (b == null) return;
b.SetupColumns(e.NewValue as ObservableCollection<Column>);
}
public void SetupColumns(ObservableCollection<Column> oldColumns)
{
if(oldColumns != null)
{
oldColumns.CollectionChanged -= Columns_CollectionChanged;
}
if ((Columns?.Count ?? 0) == 0) return;
AssociatedObject.Columns.Clear();
foreach (var column in Columns.OrderBy(c => c.Index))
{
AddColumn(column);
}
Columns.CollectionChanged += Columns_CollectionChanged;
}
private void Columns_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
var lookup = AssociatedObject.Columns.Select((c, i) => new { Index = i, Element = c.Header.ToString() }).ToLookup(ci => ci.Element, ci => ci.Index);
foreach (var c in Columns)
{
// store the index in the Model (ColumnInfo)
c.Index = lookup[c.HeaderName].FirstOrDefault();
}
}
}
Enjoy!

Resources