This a dynamic listview with dynamic header and rows. But the problem here is wen i try to use a textbox as
xaml = "<DataTemplate><TextBox VerticalAlignment=\"Center\" TextChanged=\"{Binding " + propName + "}\" > " + propName + "</TextBox></DataTemplate>";
instead of a checkbox with a binding in the method CreateDataTemplate the values can't be extratcted after the btn is clicked.
Here is the code with CheckBox. So can anybody plz help me out. and i also need the values which will be inside the textbox. Thank you in advance
<Window x:Class="WpfListView.SalesPerson_SalesRegion_Association"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="SalesPerson_SalesRegion_Association" Height="500" Width="500">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<ListView Name="listView1" Width="400" Height="300" Margin="20" HorizontalAlignment="Left">
<ListView.View>
<GridView></GridView>
</ListView.View>
</ListView>
<Button Grid.Row="1" HorizontalAlignment="Left"
Content="ShowSelectedMapping"
Name="btnShow" Width="150" Margin="0,10,0,0" Click="btnShow_Click"></Button>
<TextBlock Name="textBlock1" Grid.Row="2"
HorizontalAlignment="Left" Margin="0,10,0,0"></TextBlock>
</Grid>
public partial class SalesPerson_SalesRegion_Association : Window
{
public SalesPerson_SalesRegion_Association()
{
InitializeComponent();
AddColumnsToListView();
DataTable dt = DataHelper.GetRegionPersonAssociation();
listView1.ItemsSource = dt.DefaultView;
}
private void btnShow_Click(object sender, RoutedEventArgs e)
{
DataView view = listView1.ItemsSource as DataView;
DataTable userSelectionTbl = view.ToTable();
DataTable idTable = DataHelper.GetRegionIdPersonIdMatrix();
List<SalesRegion> lstRegion = SalesRegion.GetRegions();
string selectedRegion = string.Empty;
string msg = string.Empty;
DataRow dRow=null;
int totRows = userSelectionTbl.Rows.Count;
int totCols = lstRegion.Count-1;
string strTempMsg = string.Empty;
bool isColChecked = false;
for (int rowIndex = 0; rowIndex < totRows; rowIndex++)
{
dRow = userSelectionTbl.Rows[rowIndex];
strTempMsg = dRow[0].ToString() + "(" + idTable.Rows[rowIndex][0].ToString() + ")" + " : ";
string rgnId="";
isColChecked = false;
foreach (SalesRegion region in lstRegion)
{
if (((bool)dRow[region.RegionName]) == true)
{
rgnId = idTable.Rows[rowIndex][region.RegionName].ToString();
strTempMsg += region.RegionName + "(" + rgnId + ")";
isColChecked = true; }
}
if (isColChecked == false)
{
strTempMsg += " : No region selected";
}
strTempMsg += Environment.NewLine;
msg += strTempMsg;
}
textBlock1.Text = msg;
string tt = "t";
}
private void AddColumnsToListView()
{
List<SalesRegion> lstSalesRegion = SalesRegion.GetRegions();
List<SalesPerson> lstSalesPerson = SalesPerson.GetSalesPersons();
GridViewColumn colSalesPerson = new GridViewColumn();
colSalesPerson.Header = "Sales Person";
colSalesPerson.DisplayMemberBinding = new Binding("SalesPersonName");
colSalesPerson.Width = 150;
GridView grdView = listView1.View as GridView;
grdView.Columns.Add(colSalesPerson);
//Since columns are dynamic we need a data template per column
// in which we bind the checkBox's checked property with
//appropriate columnName
Dictionary<string, DataTemplate> dict = GetDataTemplates(lstSalesRegion);
foreach (SalesRegion region in lstSalesRegion)
{
GridViewColumn col1 = new GridViewColumn();
col1.Header = region.RegionName;
DataTemplate dTempl = dict[region.RegionName];
col1.CellTemplate = dTempl;
grdView.Columns.Add(col1);
}
}
private Dictionary<string, DataTemplate> GetDataTemplates(List<SalesRegion> lstSalesRegion)
{
Dictionary<string, DataTemplate> dict = new Dictionary<string, DataTemplate>();
foreach (SalesRegion region in lstSalesRegion)
{
DataTemplate dTemplate = CreateDataTemplate(region.RegionName);
dict.Add(region.RegionName, dTemplate);
}
return dict;
}
private DataTemplate CreateDataTemplate(string propName)
{
MemoryStream sr = null;
ParserContext pc = null;
string xaml = string.Empty;
xaml = "<DataTemplate><CheckBox VerticalAlignment=\"Center\" IsChecked=\"{Binding " + propName + "}\"></CheckBox></DataTemplate>";
sr = new MemoryStream(Encoding.ASCII.GetBytes(xaml));
pc = new ParserContext();
pc.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
pc.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml");
DataTemplate datatemplate = (DataTemplate)XamlReader.Load(sr, pc);
return datatemplate;
}
} // class ends here
} // DataHelper classes
public class SalesPerson
{
public int SalesPersonId
{ get; set; }
public string SalesPersonName
{ get; set; }
public SalesPerson(int salesPersonId, string salesPersonName)
{
this.SalesPersonId = salesPersonId;
this.SalesPersonName = salesPersonName;
}
public static List<SalesPerson> GetSalesPersons()
{
List<SalesPerson> lst = new List<SalesPerson>();
lst.Add(new SalesPerson(101, "SalesPerson1"));
lst.Add(new SalesPerson(201, "SalesPerson2"));
lst.Add(new SalesPerson(301, "SalesPerson3"));
lst.Add(new SalesPerson(401, "SalesPerson4"));
lst.Add(new SalesPerson(501, "SalesPerson5"));
return lst;
}
} // class SalesPerson ends here
public class SalesRegion
{
public int RegionId
{ get; set; }
public string RegionName
{ get; set; }
public SalesRegion(int regionId, string regionName)
{
this.RegionId = regionId;
this.RegionName = regionName;
}
public static List<SalesRegion> GetRegions()
{
List<SalesRegion> lst = new List<SalesRegion>();
lst.Add(new SalesRegion(501,"North"));
lst.Add(new SalesRegion(502, "South"));
lst.Add(new SalesRegion(503, "East"));
lst.Add(new SalesRegion(504, "West"));
lst.Add(new SalesRegion(505, "MyRegion"));
return lst;
}
} // class SalesRegion ends here
public class DataHelper
{
public static DataTable GetRegionPersonAssociation()
{
DataTable dt = new DataTable();
//Create data table structure
// SalesPerson Region1 Region2 Region3 ....
DataColumn colSalesPerson = new DataColumn("SalesPersonName", typeof(string));
dt.Columns.Add(colSalesPerson);
List<SalesRegion> lstRegions = SalesRegion.GetRegions();
DataColumn colRegion = null;
foreach (SalesRegion region in lstRegions)
{
colRegion = new DataColumn(region.RegionName, typeof(bool));
dt.Columns.Add(colRegion);
}
//Fill data into the data table
List<SalesPerson> personList = SalesPerson.GetSalesPersons();
DataRow dRow = null;
foreach (SalesPerson sp in personList)
{
dRow = dt.NewRow();
dRow["SalesPersonName"] = sp.SalesPersonName;
foreach (SalesRegion sr in lstRegions)
{
dRow[sr.RegionName] = false;
}
dt.Rows.Add(dRow);
}
return dt;
}
public static DataTable GetRegionIdPersonIdMatrix()
{
DataTable dt = new DataTable();
//Create data table structure
// SalesPerson Region1 Region2 Region3 ....
DataColumn colSalesPerson = new DataColumn("SalesPersonId", typeof(int));
dt.Columns.Add(colSalesPerson);
List<SalesRegion> lstRegions = SalesRegion.GetRegions();
DataColumn colRegion = null;
foreach (SalesRegion region in lstRegions)
{
colRegion = new DataColumn(region.RegionName, typeof(int));
dt.Columns.Add(colRegion);
}
//Fill data into the data table
List<SalesPerson> personList = SalesPerson.GetSalesPersons();
DataRow dRow = null;
foreach (SalesPerson sp in personList)
{
dRow = dt.NewRow();
dRow["SalesPersonId"] = sp.SalesPersonId;
foreach (SalesRegion sr in lstRegions)
{
dRow[sr.RegionName] = sr.RegionId;
}
dt.Rows.Add(dRow);
}
return dt;
} } // class DataHelper ends here
use a textbox data template like this
xaml = "<DataTemplate><TextBox VerticalAlignment=\"Center\" Tag=\"{Binding " + propName + ", Mode=TwoWay}\" > " + propName + "</TextBox></DataTemplate>";
add a style for textboxes to your listview.resources
<Style TargetType="{x:Type TextBox}">
<EventSetter Event="TextChanged" Handler="TextBox_TextChanged"></EventSetter>
</Style>
add the handler to your codebehind
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
(sender as TextBox).Tag = true;
}
this will behave like your checkbox example.
Related
I am trying to create a table whose cells are dynamic in width and height. Following is my xaml code:
<ItemsControl Grid.Row="1" Grid.Column="1" DataContext="{Binding GameBoardApp}" ItemsSource="{Binding BlockList}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel></WrapPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Grid.Row" Value="{Binding Row}"/>
<Setter Property="Grid.Column" Value="{Binding Col}"/>
<Setter Property="Grid.Width" Value="{Binding Width, Mode=TwoWay}" />
<Setter Property="Grid.Height" Value="{Binding Height, Mode=TwoWay}" />
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderThickness="1" BorderBrush="Black">
<Grid>
<Rectangle Fill="{Binding Background}" />
<TextBlock Text="{Binding Name}"/>
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
I am able to design the UI and see the content but I am not able to set up 2-way data binding to change the width of the cell. Following is my Code Behind:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
GameBoardApp = new GameBoard(50);
DataContext = this;
}
public GameBoard GameBoardApp { get; set; }
private void IncreaseSize_Click(object sender, RoutedEventArgs e)
{
GameBoardApp = new GameBoard(GameBoardApp.CellWidth + 1);
Debug.Print(GameBoardApp.CellWidth.ToString());
}
private void DecreaseSize_Click(object sender, RoutedEventArgs e)
{
GameBoardApp = new GameBoard(GameBoardApp.CellWidth-1);
Debug.Print(GameBoardApp.CellWidth.ToString());
}
}
public class GameBoard : INotifyPropertyChanged
{
public GameBoard(int cellWidthVal)
{
_cellWidth = cellWidthVal;
var m1 = new Block() { Name = "b1", Background = Brushes.Red, Col = 50, Row = 50, Width = CellWidth };
var m2 = new Block() { Name = "b2", Background = Brushes.Gray, Col = 50, Row = 50, Width = CellWidth };
var m3 = new Block() { Name = "b3", Background = Brushes.Goldenrod, Col = 0, Row = 0, Width = CellWidth };
var m4 = new Block() { Name = "b4", Background = Brushes.Honeydew, Col = 0, Row = 0, Width = CellWidth };
var m5 = new Block() { Name = "b5", Background = Brushes.Bisque, Col = 70, Row = 70, Width = CellWidth };
var m6 = new Block() { Name = "b6", Background = Brushes.Honeydew, Col = 0, Row = 0, Width = CellWidth };
var m7 = new Block() { Name = "b7", Background = Brushes.Honeydew, Col = 0, Row = 0, Width = CellWidth };
var m8 = new Block() { Name = "b1", Background = Brushes.Red, Col = 0, Row = 0, Width = CellWidth };
var m9 = new Block() { Name = "b2", Background = Brushes.Gray, Col = 0, Row = 0, Width = CellWidth };
var m10 = new Block() { Name = "b3", Background = Brushes.Goldenrod, Col = 0, Row = 0, Width = CellWidth };
var m11 = new Block() { Name = "b4", Background = Brushes.Honeydew, Col = 0, Row = 0, Width = CellWidth };
var m12 = new Block() { Name = "b5", Background = Brushes.Honeydew, Col = 0, Row = 0, Width = CellWidth };
var m13 = new Block() { Name = "b6", Background = Brushes.Honeydew, Col = 0, Row = 0, Width = CellWidth };
var m14 = new Block() { Name = "bhg jg7", Background = Brushes.Honeydew, Col = 0, Row = 0, Width = CellWidth };
_blockList = new ObservableCollection<Block>() { m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11};
}
int _cellWidth;
public int CellWidth { get { return _cellWidth; } set { _cellWidth = value; RaisePropertyChanged("CellWidth"); } }
ObservableCollection<Block> _blockList;
public ObservableCollection<Block> BlockList { get { return _blockList; } set { _blockList = value; RaisePropertyChanged("BlockList"); } }
public event PropertyChangedEventHandler PropertyChanged;
void RaisePropertyChanged(string propname)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propname));
}
}
public class Block : INotifyPropertyChanged
{
int _row;
public int Row { get { return _row; } set { _row = value; RaisePropertyChanged("Row"); } }
int _col;
public int Col { get { return _col; } set { _col = value; RaisePropertyChanged("Col"); } }
string _name;
public string Name { get { return _name; } set { _name = value; RaisePropertyChanged("Name"); } }
Brush _background;
public Brush Background { get { return _background; } set { _background = value; RaisePropertyChanged("Background"); } }
int _width = 50;
public int Width { get { return _width; } set { _width = value; RaisePropertyChanged("Width"); } }
int _height = 50;
public int Height { get { return _height; } set { _height = value; RaisePropertyChanged("Width"); } }
public event PropertyChangedEventHandler PropertyChanged;
void RaisePropertyChanged(string propname)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propname));
}
}
I am trying to refresh the ItemControl once I make the changes in GameBoard but not able to do it.
Preferably I would want to change the width with only one width variable in GameBoard class but looks like that will not be possible here
Regards
Fix your ItemContainerStyle to target the ContentPresenter and bind its Width and Height properties to your source properties:
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Width" Value="{Binding Width}" />
<Setter Property="Height" Value="{Binding Height}" />
</Style>
</ItemsControl.ItemContainerStyle>
And since you are creating a new GameBoard object in your click event handlers, you also need to implement the INotifyPropertyChanged interface and raise change notifications in the window:
public partial class MainWindow : Window, INotifyPropertyChanged
{
public MainWindow()
{
InitializeComponent();
GameBoardApp = new GameBoard(50);
DataContext = this;
}
private GameBoard _gameBoardApp;
public GameBoard GameBoardApp
{
get { return _gameBoardApp; }
set { _gameBoardApp = value; RaisePropertyChanged(); }
}
private void IncreaseSize_Click(object sender, RoutedEventArgs e)
{
GameBoardApp = new GameBoard(GameBoardApp.CellWidth + 1);
Debug.Print(GameBoardApp.CellWidth.ToString());
}
private void DecreaseSize_Click(object sender, RoutedEventArgs e)
{
GameBoardApp = new GameBoard(GameBoardApp.CellWidth - 1);
Debug.Print(GameBoardApp.CellWidth.ToString());
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
This should make your example work as expected.
As a side note, the Grid.Row and Grid.Column attached properties are not useful when you host your item containers in a WrapPanel.
I am learning Caliburn.Micro. I am storing data from database into the DataGrid. I am able to access the data but not able to delete the data from DataGrid in CaliBurn.Micro. In my project I wants to have delete button in every row so that whenever i click the button of specific row then that row data will be deleted. I have tried but it is not working.
Here is my code
ShellView.xaml
<Button x:Name="ButtonUpdate" Width="100" Height="30" Content="Update"/>
<DataGrid x:Name="Empdata2" AutoGenerateColumns="False" ItemsSource="{Binding Path= Empdata}" SelectedItem="{Binding selecteditem}" Height="162" CanUserAddRows="False">
<DataGrid.Columns>
<DataGridTextColumn Header=" First Name" Binding="{Binding Path= fname}"/>
<DataGridTextColumn Header="Last Name" Binding="{Binding Path=lname}"/>
<DataGridTemplateColumn Header="delete">
<DataGridTemplateColumn.CellTemplate >
<DataTemplate>
<Button Content="Delete" x:Name="DeleteButton"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
ShellViewModel.cs
public class ShellViewModel : Caliburn.Micro.PropertyChangedBase, IShell
{
private string _firstname, _lastname;
private ObservableCollection<Person> _empdata = new ObservableCollection<Person>();
public ObservableCollection<Person> Empdata
{
get { return _empdata; }
set
{
_empdata = value;
NotifyOfPropertyChange(() => Empdata);
}
}
Person model = new Person();
public string FirstName
{
get { return _firstname; }
set { _firstname = value; }
}
public string LastName
{
get { return _lastname; }
set { _lastname = value; }
}
Auth obj = new Auth();
public void ButtonUpdate()
{
DataSet d = new DataSet();
d = obj.updateuser();
for (int i = 0; i < d.Tables[0].Rows.Count; i++)
Empdata.Add(new Person
{
fname = d.Tables[0].Rows[i][0].ToString(),
lname = d.Tables[0].Rows[i][1].ToString(),
});
}
private Person _selecteditem;
public Person selecteditem
{
get { return _selecteditem; }
set
{
_selecteditem = value;
NotifyOfPropertyChange(() => selecteditem);
}
}
string sel;
public void DeleteButton()
{
Auth obj = new Auth();
sel = selecteditem.fname.ToString();
bool find = obj.deluser(sel);
if (find == true)
{
MessageBox.Show("Deleted");
}
}
}
Person.cs
public class Person:PropertyChangedBase
{
public string FirstName { get; set; }
public string LastName { get; set; }
private string Firstname;
public string fname
{
get { return Firstname; }
set
{
Firstname = value;
NotifyOfPropertyChange(() => fname);
}
}
private string Lastname;
public string lname
{
get { return Lastname; }
set
{
Lastname = value;
NotifyOfPropertyChange(() => lname);
}
}
}
Auth.cs
public class Auth
{
SqlConnection conn = new SqlConnection(#"Data Source = a; Initial Catalog = ab; Persist Security Info=True;User ID = s; Password=123");
public DataSet updateuser()
{
try
{
conn.Open();
SqlCommand comm = new SqlCommand("Select * from [add]", conn);
DataSet ds = new DataSet();
SqlDataAdapter da = new SqlDataAdapter(comm);
da.Fill(ds);
conn.Close();
return ds;
}
catch (Exception ex)
{
throw ex;
}
}
public bool deluser(string name)
{
try
{
conn.Open();
SqlCommand comm = new SqlCommand("Delete from [add] where firstname=" + name + "", conn);
comm.ExecuteNonQuery();
conn.Close();
return true;
}
catch(Exception ex)
{
throw ex;
}
}
}
Set the cal:Bind.Model attached property to your view model:
<DataTemplate xmlns:cal="http://www.caliburnproject.org">
<Button Content="Press Me" VerticalAlignment="Top"
cal:Bind.Model="{Binding DataContext, RelativeSource={RelativeSource AncestorType=DataGrid}}"
x:Name="DeleteButton" />
</DataTemplate>
Then the DeleteButton method of the ShellViewModel should be called when the button is clicked.
i have big problem with binding Stacked Column Series to my chart.
I have
public ObservableCollection Series property in my ViewModel and try by many ways but it still not working.
This is code from ViewModel to prepare Series:
private void drawChart()
{
this.Series.Clear();
var dataValues = new List<List<SimpleDataValue>>();
int wartoscNiezalezna = 1;
for (int i = 0; i < 2; i++)
{
dataValues.Add(new List<SimpleDataValue>());
}
foreach (var item in myCollection)
{
var param = someparam;
dataValues[0].Add(new SimpleDataValue { IndependentValue = "Czujnik " + wartoscNiezalezna, DependentValue = 100 });
//czerwone
dataValues[1].Add(new SimpleDataValue { IndependentValue = "" + wartoscNiezalezna, DependentValue = 200 });
wartoscNiezalezna++;
}
var stackedSeries = Activator.CreateInstance(typeof(StackedColumnSeries)) as DefinitionSeries;
int itemnr=0;
foreach (var item in dataValues)
{
var definicja = new SeriesDefinition();
if(itemnr==0)
definicja.Title = "Stan 1";
else
definicja.Title = "Stan 2";
definicja.DependentValuePath = "DependentValue";
definicja.IndependentValuePath = "IndependentValue";
definicja.ToolTip = "asdas";
definicja.ItemsSource = item;
stackedSeries.SeriesDefinitions.Add(definicja);
itemnr++;
}
Series.Add(stackedSeries);
}
I cant bind it to:
<charting:Chart x:Name="MyChart" Padding="10,10,10,10">
<charting:Chart.Series>
<charting:StackedColumnSeries>
<charting:SeriesDefinition ItemsSource="{Binding Series}" DependentValuePath="DependentValue" IndependentValuePath="IndependentValue">
</charting:SeriesDefinition>
</charting:StackedColumnSeries>
</charting:Chart.Series>
</charting:Chart>
I was trying with SeriesDefinitions Collection and others.
I will be very grateful to some help.
I hope I've answered your question there
Anyway I post the second part of my answer here:
MainWindow.xaml:
<charting:Chart x:Name="MyChart" Padding="10,10,10,10">
<charting:Chart.Series>
<charting:StackedColumnSeries>
<charting:SeriesDefinition Title="Stan 1" ItemsSource="{Binding FirstCollection}" DependentValuePath="DependentValue" IndependentValuePath="IndependentValue" />
<charting:SeriesDefinition Title="Stan 2" ItemsSource="{Binding SecondCollection}" DependentValuePath="DependentValue" IndependentValuePath="IndependentValue" />
</charting:StackedColumnSeries>
</charting:Chart.Series>
</charting:Chart>
MainWindow.xaml.cs
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
this.MyChart.DataContext = new ChartModel
{
FirstCollection = Enumerable.Range(1, 10).Select(i => new SimpleDataValue { IndependentValue = "Czujnik " + i, DependentValue = 100 }).ToList(),
SecondCollection = Enumerable.Range(1, 10).Select(i => new SimpleDataValue { IndependentValue = "" + i, DependentValue = 200 }).ToList()
};
}
}
public class SimpleDataValue
{
public string IndependentValue { get; set; }
public int DependentValue { get; set; }
}
public class ChartModel
{
public List<SimpleDataValue> FirstCollection { get; set; }
public List<SimpleDataValue> SecondCollection { get; set; }
}
I am not sure with the syntax but the logic should be like below:
ViewModel
public class GraphItem {
public string IndependentValue { get; set; }
public int DependentValue1 { get; set; }
public int DependentValue2 { get; set; }
}
public class ChartViewModel
{
private List<GraphItem> itemCollection;
public List<GraphItem> ItemCollection
{
get { return itemCollection;}
set {
itemCollection=value;
OnPropertyChanged("ItemCollection");
}
}
public ChartViewModel()
{
//Bind ItemCollection
}
}
Xaml:
<charting:Chart x:Name="MyChart" Padding="10,10,10,10" DataContext={Binding ItemCollection}">
<charting:Chart.Series>
<charting:StackedColumnSeries>
<charting:SeriesDefinition Title="Stan 1" ItemsSource="{Binding}" DependentValuePath="DependentValue1" IndependentValuePath="IndependentValue" />
<charting:SeriesDefinition Title="Stan 2" ItemsSource="{Binding}" DependentValuePath="DependentValue2" IndependentValuePath="IndependentValue" />
</charting:StackedColumnSeries>
</charting:Chart.Series>
</charting:Chart>
May this help.
I'm using AutoCompleteBox from the wpf toolkit and I implement the populating by my own
since there is a lot of data and I want to do the search in a background thread.
this is what heppans when I search for the number 12.
while it should show me 4 results - 12,120,121,122.
What am I doing wrong ?
Guide on msdn that I tried to folow: http://msdn.microsoft.com/en-us/library/system.windows.controls.autocompletebox.populating(VS.95).aspx
XAML:
<Grid>
<Controls:AutoCompleteBox x:Name="txtSearch" Populating="AutoCompleteBox_Populating" Height="30" Background="Beige" />
</Grid>
Code behind:
public partial class Window1 : Window {
private int MAX_NUM_OF_RESULTS = 3;
public List<Person> Persons { get; set; }
public List<string> Results { get; set; }
public Window1() {
InitializeComponent();
Persons = new List<Person>();
for (var i = 0; i < 1000000; i++) {
Persons.Add(new Person { Name = i.ToString() });
}
Results = new List<string>();
}
private void AutoCompleteBox_Populating(object sender, PopulatingEventArgs e) {
e.Cancel = true;
var b = new BackgroundWorker();
b.RunWorkerAsync(txtSearch.SearchText);
b.DoWork += b_DoWork;
b.RunWorkerCompleted += b_RunWorkerCompleted;
}
void b_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
txtSearch.ItemsSource = Results;
txtSearch.PopulateComplete();
}
void b_DoWork(object sender, DoWorkEventArgs e) {
Results.Clear();
var counter = 0;
foreach (var person in Persons) {
if (person.Name.StartsWith(e.Argument.ToString())) {
Results.Add(person.Name);
counter++;
if (counter > MAX_NUM_OF_RESULTS) {
break;
}
}
}
}
}
Class Person:
public class Person {
public string Name;
}
Try change the order to the following
var b = new BackgroundWorker();
b.DoWork += b_DoWork;
b.RunWorkerCompleted += b_RunWorkerCompleted;
b.RunWorkerAsync(txtSearch.SearchText);
Are you certain your search logic is actually executing? If so, are the expected results in Results prior to assigning them to ItemsSource?
I think this:
var b = new BackgroundWorker();
b.RunWorkerAsync(txtSearch.SearchText);
b.DoWork += b_DoWork;
b.RunWorkerCompleted += b_RunWorkerCompleted;
Should be this:
var b = new BackgroundWorker();
b.DoWork += b_DoWork;
b.RunWorkerCompleted += b_RunWorkerCompleted;
b.RunWorkerAsync(txtSearch.SearchText);
Otherwise you risk having the worker start before setting up event handlers.
I have a DataGrid, bound to Database table, I need to get the content of selected row in DataGrid, for example, I want to show in MessageBox content of selected row.
Example of DataGrid:
So, if I select the second row, my MessageBox has to show something like: 646 Jim Biology.
You can use the SelectedItem property to get the currently selected object, which you can then cast into the correct type. For instance, if your DataGrid is bound to a collection of Customer objects you could do this:
Customer customer = (Customer)myDataGrid.SelectedItem;
Alternatively you can bind SelectedItem to your source class or ViewModel.
<Grid DataContext="MyViewModel">
<DataGrid ItemsSource="{Binding Path=Customers}"
SelectedItem="{Binding Path=SelectedCustomer, Mode=TwoWay}"/>
</Grid>
If you're using the MVVM pattern you can bind a SelectedRecord property of your VM with SelectedItem of the DataGrid, this way you always have the SelectedValue in you VM.
Otherwise you should use the SelectedIndex property of the DataGrid.
public IEnumerable<DataGridRow> GetDataGridRows(DataGrid grid)
{
var itemsSource = grid.ItemsSource as IEnumerable;
if (null == itemsSource) yield return null;
foreach (var item in itemsSource)
{
var row = grid.ItemContainerGenerator.ContainerFromItem(item) as DataGridRow;
if (null != row) yield return row;
}
}
private void DataGrid_Details_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
try
{
var row_list = GetDataGridRows(DataGrid_Details);
foreach (DataGridRow single_row in row_lis)
{
if (single_row.IsSelected == true)
{
MessageBox.Show("the row no."+single_row .GetIndex ().ToString ()+ " is selected!");
}
}
}
catch { }
}
This is pretty simple in this DataGrid dg and item class is populated in datagrid and listblock1 is a basic frame.
private void DataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
try
{
var row_list = (Item)dg.SelectedItem;
listblock1.Content = "You Selected: " + row_list.FirstName + " " + row_list.LastName;
}
catch { }
}
public class Item
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
You can also:
DataRowView row = dataGrid.SelectedItem as DataRowView;
MessageBox.Show(row.Row.ItemArray[1].ToString());
Well I will put similar solution that is working fine for me.
private void DataGrid1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
try
{
if (DataGrid1.SelectedItem != null)
{
if (DataGrid1.SelectedItem is YouCustomClass)
{
var row = (YouCustomClass)DataGrid1.SelectedItem;
if (row != null)
{
// Do something...
// ButtonSaveData.IsEnabled = true;
// LabelName.Content = row.Name;
}
}
}
}
catch (Exception)
{
}
}
#Krytox answer with MVVM
<DataGrid
Grid.Column="1"
Grid.Row="1"
Margin="10" Grid.RowSpan="2"
ItemsSource="{Binding Data_Table}"
SelectedItem="{Binding Select_Request, Mode=TwoWay}" SelectionChanged="DataGrid_SelectionChanged"/>//The binding
#region View Model
private DataRowView select_request;
public DataRowView Select_Request
{
get { return select_request; }
set
{
select_request = value;
OnPropertyChanged("Select_Request"); //INotifyPropertyChange
OnSelect_RequestChange();//do stuff
}
}
private void Fetching_Record_Grid_MouseDoubleClick_1(object sender, MouseButtonEventArgs e)
{
IInputElement element = e.MouseDevice.DirectlyOver;
if (element != null && element is FrameworkElement)
{
if (((FrameworkElement)element).Parent is DataGridCell)
{
var grid = sender as DataGrid;
if (grid != null && grid.SelectedItems != null && grid.SelectedItems.Count == 1)
{
//var rowView = grid.SelectedItem as DataRowView;
try
{
Station station = (Station)grid.SelectedItem;
id_txt.Text = station.StationID.Trim() ;
description_txt.Text = station.Description.Trim();
}
catch
{
}
}
}
}
}
Just discovered this one after i tried Fara's answer but it didn't work on my project. Just drag the column from the Data Sources window, and drop to the Label or TextBox.
use your Model class to get row values selected from datagrid like,
XDocument xmlDoc = XDocument.Load(filepath);
if (tablet_DG.SelectedValue == null)
{
MessageBox.Show("select any record from list..!", "select atleast one record", MessageBoxButton.OKCancel, MessageBoxImage.Warning);
}
else
{
try
{
string tabletID = "";
/*here i have used my model class named as TabletMode*/
var row_list = (TabletModel)tablet_DG.SelectedItem;
tabletID= row_list.TabletID;
var items = from item in xmlDoc.Descendants("Tablet")
where item.Element("TabletID").Value == tabletID
select item;
foreach (var item in items)
{
item.SetElementValue("Instance",row_list.Instance);
item.SetElementValue("Database",row_list.Database);
}
xmlDoc.Save(filepath);
MessageBox.Show("Details Updated..!"
+ Environment.NewLine + "TabletId: " +row_list.TabletID + Environment.NewLine
+ "Instance:" + row_list.Instance + Environment.NewLine + "Database:" + row_list.Database, "", MessageBoxButton.YesNoCancel, MessageBoxImage.Information);
}
catch (Exception ex)
{
MessageBox.Show(ex.StackTrace);
}
}
if I select the second row -
Dim jason As DataRowView
jason = dg1.SelectedItem
noteText.Text = jason.Item(0).ToString()
noteText will be 646. This is VB, but you get it.
There are a lot of answers here that probably work in a specific context, but I was simply trying to get the text value of the first cell in a selected row. While the accepted answer here was the closest for me, it still required creating a type and casting the row into that type. I was looking for a simpler solution, and this is what I came up with:
MessageBox.Show(((DataRowView)DataGrid.SelectedItem).Row[0].ToString());
This gives me the first column in the selected row. Hopefully this helps someone else.
I got something like this:
private void DataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e) {
DataGrid dg = (DataGrid)sender;
DataRowView selectedRow = dg.SelectedItem as DataRowView;
if(selectedRow != null) {
txtXXX.Text = selectedRow["xxx"].ToString();
txtYYY.Text = selectedRow["yyy"].ToString();
txtZZZ.Text = selectedRow["zzz"].ToString();
}
}
Your front code:
set your model namespace xmlns:viewModel="clr-namespace:CPL3_workstation.MVVM.ModelViews.Tables"
set xmlns:d="http://schemas.microsoft.com/expression/blend/2008", because d:DataContext="{d:DesignInstance...}
<DataGrid d:DataContext = "{d:DesignInstance viewModel:TestViewModel, IsDesignTimeCreatable = True}"
ItemsSource = "{Binding Rows}"
SelectedItem = "{Binding Selector}">
<DataGrid.Columns>
<DataGridTextColumn
Binding = "{Binding Content1}"
Header = "Column 1" />
<DataGridTextColumn
Binding = "{Binding Content2}"
Header = "Column 2" />
<DataGridTextColumn
Binding = "{Binding Content3}"
Header = "Column 3" />
</DataGrid.Columns>
</DataGrid>
Your ViewModel and the Model below:
namespace CPL3_workstation.MVVM.ModelViews.Tables
{
public class TestViewModel
{
public IEnumerable<TestModel> Rows { get; set; }
public TestModel Selector
{
get => selector;
set => selector = value;
}
private TestModel selector;
public TestViewModel()
{
Rows = new List<TestModel>
{
new TestModel{ Content1 = "one", Content2 = "two", Content3 = "three" },
new TestModel{ Content1 = "one", Content2 = "two", Content3 = "three" },
new TestModel{ Content1 = "one", Content2 = "two", Content3 = "three" },
new TestModel{ Content1 = "one", Content2 = "two", Content3 = "three" }
};
}
}
public class TestModel
{
public string Content1 { get; set; }
public string Content2 { get; set; }
public string Content3 { get; set; }
}
}
As you can see, the SelectedItem has a binding to the Selector property of the type of your model.