Adding CheckBox to all columns in radgrid Header - checkbox

How to add checkbox to all the header columns (Like in the image) and get the checked value, here autogeneratecolumns is true. Pls suggest programmatically or Clientside. I tried telerik demos but not much of help from there.
enter image description here
Correction in Img: For all the columns, Including Article Type.

There are multiple ways to get the desired result but here is the first solution I could come up with. I'd need to know a lot more about the exact requirements in order to find the best solution for your situation.
Based on the current information you've provided, this is the best I could come up with:
First you'll want to implement the OnAutoGeneratingColumn event of your GridView.
<telerik:RadGridView x:Name="MyGridView" AutoGenerateColumns="True" AutoGeneratingColumn="MyGridView_OnAutoGeneratingColumn" ItemsSource="{Binding MyData}" />
In this event you can customize the columns being generated. You could for example escape the generation of certain columns or customize anything you want really. In your situation you'll want to add a CheckBox to the Header of course.
private void MyGridView_OnAutoGeneratingColumn(object sender, GridViewAutoGeneratingColumnEventArgs e)
{
//Extra1: Ignore this event for certain columns
if (e.Column.UniqueName.Contains("extra1"))
{
return;
}
//Extra2: Disable the generation of a column entirely
if (e.Column.UniqueName.Equals("extra2"))
{
e.Cancel = true;
return;
}
//Place a CheckBox inside the header
e.Column.Header = new StackPanel()
{
Orientation = Orientation.Vertical,
Children =
{
new TextBlock()
{
Text = e.Column.UniqueName,
Margin = new Thickness(2),
HorizontalAlignment = HorizontalAlignment.Center
},
new CheckBox()
{
Margin = new Thickness(2),
HorizontalAlignment = HorizontalAlignment.Center
}
}
};
}
This should now give you the desired result as shown on your screenshot.
The second part is to get the list of checked columns. For this part I don't really know what exactly you're looking for but I'll just give you something to get you started.
Consider the following to be the OnClick event of a button:
private void MyButton_OnClick(object sender, RoutedEventArgs e)
{
var cols = new List<GridViewColumn>();
foreach (var col in MyGridView.Columns)
{
var hc = MyGridView.ChildrenOfType<GridViewHeaderCell>().FirstOrDefault(q => q.Column != null && q.Column.UniqueName == col.UniqueName && q.Column.DisplayIndex == col.DisplayIndex);
if (hc == null) continue;
var cb = hc.FindChildByType<CheckBox>();
if (cb != null && cb.IsChecked == true)
cols.Add(col);
}
MessageBox.Show(string.Join(", ", cols.Select(q => q.UniqueName)));
}
If you have any more questions or need any more help, just leave a comment.
Update: I was using the WPF version of telerik which is why I used the telerik:RadGridView. I didn't realize you were using the ASP.NET AJAX version which makes yours a telerik:RadGrid.
I believe the equivalent of my OnAutoGeneratingColumn event would be OnColumnCreated in your version, here is the documentation of telerik
I'd also appreciate it if you could mark this as the answer if this solved your problem, or at least give this an up-vote if this helped you in any way.

Related

Adding a checkbox column to the infragistics ultrawingrid that is bind to a datasource

I am trying to add a new checkbox column to the ultrawingrid that is binding to a dataset, when ever I add a new column it says key not found, any ideas on how to fix it, Thank you...
Below is the code
private void grdPayVis_InitializeLayout(object sender, InitializeLayoutEventArgs e)
{
var gridBand = grdPayVis.DisplayLayout.Bands[0];
gridBand.Columns["Select"].Header.Caption = "Select";
gridBand.Columns["Select"].Header.Appearance.TextHAlign = HAlign.Center;
gridBand.Columns["Select"].Header.VisiblePosition = 0;
gridBand.Columns["Select"].Hidden = false;
gridBand.Columns["Select"].Style = Infragistics.Win.UltraWinGrid.ColumnStyle.CheckBox;
gridBand.Columns["Select"].AutoSizeMode = ColumnAutoSizeMode.AllRowsInBand;
gridBand.Columns["Select"].CellActivation = Activation.AllowEdit;
gridBand.Columns["Select"].CellAppearance.TextHAlign = HAlign.Center;
gridBand.Columns["Select"].CellClickAction = CellClickAction.Edit;
}
Swetha
Steve's answer above is good, but it can be simplified and made better in a couple of ways.
First, a lot of that code isn't really necessary. For example, the default Hidden state of a column is false, so there's no need to set that. Same for AutoSizeMode and CellClickAction.
Also, if you add an unbound column, it's default DataType is string, which doesn't make a lot of sense for a CheckBox column. By setting the DataType to bool, you can avoid the need to set the Style and also clear up the problem of every cell being indeterminate by default.
private void ultraGrid1_InitializeLayout(object sender, Infragistics.Win.UltraWinGrid.InitializeLayoutEventArgs e)
{
UltraGridLayout layout = e.Layout;
UltraGridBand rootBand = layout.Bands[0];
if (false == rootBand.Columns.Exists("Select"))
{
UltraGridColumn checkBoxColumn = rootBand.Columns.Add("Select");
checkBoxColumn.Header.VisiblePosition = 0;
checkBoxColumn.DataType = typeof(bool);
}
}
As for determining the value of the cell and keeping track of the 'selected' rows, you have to understand a little bit about how the grid cell editors work. To really understand it, imagine a cell that contains DateTime info. The user enters the cell and intends to type in a date, like '1/19/2015'. When the user begins typing, he starts by typing a '1'. If you check the cell's value at this point, the grid cannot possibly convert the current text in the cell ("1") into a date. So because of this, the grid doesn't attempt to update the underlying data source with the value until something else happens, like if the user leaves the cell or loses focus on the grid.
Of course, if the cell has a checkbox, then this problem doesn't exist, since the user is incapable of entering an invalid value, but the grid still works the same way and doesn't update the value until the user leaves the cell.
So... when you are dealing with any cell that is NOT in edit mode (not currently active) then you can use the Value property of the cell reliably. When the cell is in edit mode (is active) then you can't rely on the Value, which reads from the data source, you have to use the cell's Text.
Therefore, given any cell in a boolean (checkbox) column, to get an accurate reflection of the current state of the checkbox on the screen, you would do something like this:
private bool GetCheckBoxCellCurrentValue(UltraGridCell cell)
{
if (cell.IsInEditMode)
return bool.Parse(cell.Text);
else
return (bool)cell.Value;
}
Finally, the grid doesn't keep any kind of list of the 'checked' cells. But you could do this yourself without too much difficulty. What you would have to do is build the initial list right after you bind the grid. Then trap events such as CellChange, AfterRowAdded, BeforeRowDeleted, and perhaps some others to continuously keep your list up to date.
When the grid has its datasource set to a datatable or other binding source, it automatically creates the columns present in the datatable or in the properties of the datasource. If you want to have another column you need to ADD it before trying to reference it from the Band columns
private void grdPayVis_InitializeLayout(object sender, InitializeLayoutEventArgs e)
{
var gridBand = grdPayVis.DisplayLayout.Bands[0];
// Check if the column exists, if not, add it
if(!gridBand.Columns.Exists("Select"))
gridBand.Columns.Add("Select", "Select");
// Not needed, the ADD adds the Key and the Caption
// gridBand.Columns["Select"].Header.Caption = "Select";
// Now you can reference the column with the Key = "Select"
gridBand.Columns["Select"].Header.VisiblePosition = 0;
gridBand.Columns["Select"].Hidden = false;
gridBand.Columns["Select"].Style = Infragistics.Win.UltraWinGrid.ColumnStyle.CheckBox;
gridBand.Columns["Select"].AutoSizeMode = ColumnAutoSizeMode.AllRowsInBand;
gridBand.Columns["Select"].CellClickAction = CellClickAction.Edit;
}

Telerik Radgridview for winform row changed event args contains the same value on old and new

Am using Telerik's radgridview for winforms. I am binding the radgridview to a binding list. I am trying to do some validation on this event
private void rgView_RowsChanged(object sender, GridViewCollectionChangedEventArgs e)
{
var changedRowItems = e.NewItems;
var originalRowItems = e.OldItems
var changedRow = changedRowItems[0];
var originalRow = originalRowItems[0];
var editedUser = ((Telerik.WinControls.UI.GridViewRowInfo)changedRow).DataBoundItem
as myusermodel;
var noneditedUser = ((Telerik.WinControls.UI.GridViewRowInfo)originalRow).DataBoundItem
as myusermodel;
if(editedUser.MyAttribute1!= noneditedUser.MyAttribute1)// this is always equal even when changed
{
//do something
}
}
Though the event is fired correctly on the change of MyAttribute1, I see that editedUser.MyAttribute1 is equal to noneditedUser.MyAttribute1 . Am I missing something here? Could it be because am using a binding list?
It seems like everything is fine with your code.
You're assigning the exact same value to the two variables changedRow and originalRow.
You're then comparing them and they are indeed the same.
I think that you have to use the EventArgs passed into the event handler to see which row changed and how.

Detect when a row is edited in a DataGrid

I've been trying to google this but have been unable to find a solution that works for me.
I have a DataGrid that is displaying some info from a SQL table that the client dosn't know about.
The client just sends a request to the server and gets a List<SomeClass> as a response that it then displays in a DataGrid.
I need to detect when the user makes change to a row and I need the new values that the user entered.
Currently I'm using RowEditEnding event. And the method that handles this event can then:
private void editRowEventHandler(object sender, DataGridRowEditEndingEventArgs e)
{
SomeClass sClass = e.Row.DataContext as SomeClass;
// Send sClass to the server to be saved in the database...
}
This gives me the row that was being edited. But it gives me the row before the changes, and I'm unable to figure out how to get the row after the changes happen.
Is there anyone here that knows how I can do this or can point me in a direction where I might be able to find out?
See the discussion here, to avoid reading out cell-by-cell.
private void OnRowEditEnding(object sender, DataGridRowEditEndingEventArgs e)
{
DataGrid dataGrid = sender as DataGrid;
if (e.EditAction == DataGridEditAction.Commit) {
ListCollectionView view = CollectionViewSource.GetDefaultView(dataGrid.ItemsSource) as ListCollectionView;
if (view.IsAddingNew || view.IsEditingItem) {
this.Dispatcher.BeginInvoke(new DispatcherOperationCallback(param =>
{
// This callback will be called after the CollectionView
// has pushed the changes back to the DataGrid.ItemSource.
// Write code here to save the data to the database.
return null;
}), DispatcherPriority.Background, new object[] { null });
}
}
}
In your case, you are trying to detect the change in object. It comes down to the properties of the SomeClass, thus you need to focus on "Cell" instead of "Row"
Assuming your datagrid is resultGrid, i come up with the below code:
resultGrid.CellEditEnding += resultGrid_CellEditEnding;
void resultGrid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
{
var yourClassInstance = e.EditingElement.DataContext;
var editingTextBox = e.EditingElement as TextBox;
var newValue = editingTextBox.Text;
}
the "e" also contains information about Row and Column of the Cell. Thus you will know which editor the cell is using. In this case, i assume that it is a textbox.
Hope it help.

Start and Back Button pressed in rapid succession WP7

I asked this question in a similar post but there have been significant updates since then, but still no results so I will try to re-ask the question with the updated information.
Basically I have a pivot view with 4 pivot items. If I create the scenario where I hit the windows key then rapidly press the back key my application will reopen without reconstructing (this is the expected outcome). The functionality of the application is there. I can press application bar buttons etc.
What doesn't work is the pivot items are frozen. If I was on Pivot item A and I press the start and back button quickly I come back to Pivot Item A. If I try to switch Pivot Items, the screen does not update, its "frozen" on Pivot Item A BUT the functionality of Pivot Item B is there. (I know this because the application bar Icons for Pivot Item B are now showing).
I have read many articles on proper tombstoning scenarios and how to approach this problem. My data IS being tombstoned correctly, and upon reactivation the tombstoned data works. No objects are null so I don't have any exceptions being thrown at me.
I check to see if I need to reload the Main ViewModel (I don't need to in this case so the UI elements being created initially are not being re created).
What does fix the problem however is if the application is reconstructed. Lets say I go to the marketplace from my app, let it finish loading and press back, My application will be refreshed and working fine since it properly deactivated and reconstructed istelf. I don't rely on constructors doing all the work so I am not missing any key elements not being set when they aren't fired in the windows/back button scenario.
Does anyone have any idea why my screen would not be updating?
constructor/loaded event/on navigated to event
public MainPage()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(MainPage_Loaded);
}
private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
if (App.firstTimeLoading == true)
{
App.firstTimeLoading = false;
}
BuildApplicationBar();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
this.DataContext = App.ViewModel;
App.viewIdentifier = StringResource.MainPageView;
if (!App.ViewModel.IsDataLoaded)
{
App.ViewModel.LoadData();
String bookTitle;
App.Parser.appBookInfoDict.TryGetValue(CPlayerInventoryKeys.kInventoryKeyTitleShortTitle, out bookTitle);
PivotBackground.Title = bookTitle.ToUpper();
CreatePivotItems();
}
if (App.playerController.chapterPlayer.Source == null)
App.restoreStateClass.RestoreState();
//applies the proper background image
if (App.isDarkTheme)
{
BitmapImage bitmapImage = new BitmapImage(new Uri(StringResource.PanoramaBlackImage, UriKind.Relative));
BackgroundImage.ImageSource = bitmapImage;
BackgroundImage.Opacity = .85;
}
else
{
BitmapImage bitmapImage = new BitmapImage(new Uri(StringResource.PanoramaWhiteImage, UriKind.Relative));
BackgroundImage.ImageSource = bitmapImage;
BackgroundImage.Opacity = .5;
}
if (App.firstTimeLoading == false && PivotBackground.SelectedItem != SuggestedPivotItem)
BuildApplicationBar();
else if (PivotBackground.SelectedItem == SuggestedPivotItem)
{
BuildMarketPlaceApplicationBar();
}
base.OnNavigatedTo(e);
}
I found the answer. Since I had a media element open (play/paused) and I was implementing the "non tombstoned" method of hitting windows key and back button very quickly, the media element source was corrupt. Even though I reset this source, apparently it can be ignored and not function properly. All I had to do was add a line of code to the Application Deactivated handler.
private void Application_Deactivated(object sender, DeactivatedEventArgs e)
{
App.MainAudioPlayer.Source = null; //(only showing line added)
}
The behavior you are describing seems to be solely related to the way you are manipulating data internally and constructing your layout. I tested this both in the emulator and on a couple of physical devices, both producing normal output (even when bound to a view model).
Try creating a new Pivot-based application (without all your data - just using the default template) and see if the problem persists. Also worth mentioning - are you testing on a device or in the emulator?
Are you using transitions from the toolkit?
Are they defined in XAML?
If so that could be the issue. There's a bug which is fixed in the next version.
The solution for now is to remove the transitions or define them in code.

How to set the ColumnIndex of a newly added DataGridViewButton column

I have a really annoying issue with a button cell in a DataGridView control. I'm binding the grid to a dataset at runtime. Some of the rows in the grid will be linked to pdf documents. I create a button column and add it to the grid, then I loop through the rows and based on the value of a certain column I set the text of the cell in the button column. When I step through the code I can see the ColumnIndex of the button column is 10. However when the form appears, the button text values for the rows I want are blank.
When I click the button I check in the CellContentClick event to see if the ColumnIndex is 10 (which is the button column) it tells me the ColumnIndex is 0, even though it's the last column. Then when I reload the grid I call the BindHistoryGrid method again which drops the column if it exists and re-adds it. This time it sets the button text correctly. Is there some strange behavior going on that I can't see? How do I set the button ColumnIndex to 10 the first time I add it (even though it tells me that it's 10)?
private DataGridViewButtonColumn PDFButtonColumn;
private void BindHistoryGrid()
{
dataGridViewStmt.DataSource = ah.getAccountHistory(0, dateTimePicker1.Value, dateTimePicker2.Value);
if (dataGridViewStmt.Columns["GetPDFFile"] != null)
dataGridViewStmt.Columns.Remove("GetPDFFile");
dataGridViewStmt.Columns[0].DisplayIndex = 0;
dataGridViewStmt.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
dataGridViewStmt.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);
dataGridViewStmt.Columns[0].Visible = false;
dataGridViewStmt.Columns[1].Visible = false;
dataGridViewStmt.Columns.Add(PDFButtonColumn);
dataGridViewStmt.RowHeadersVisible = false;
dataGridViewStmt.ReadOnly = true;
dataGridViewStmt.AllowUserToAddRows = false;
foreach (DataGridViewRow row in dataGridViewStmt.Rows)
{
//if (((string)row.Cells[5].Value).Contains("Invoice"))
if (((int)row.Cells[9].Value) > 0)
{
((DataGridViewButtonCell)(row.Cells[10])).Value = "Get Invoice";
}
else
{
((DataGridViewButtonCell)(row.Cells[10])).Value = "";
}
}
}
private void dataGridViewStmt_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == 10 && dataGridViewStmt.CurrentRow.Cells[6].Value != System.DBNull.Value)
{
string pdfFile = "";
int docID = 0;
pdfFile = (string)dataGridViewStmt.CurrentRow.Cells[5].Value + ".pdf";
docID = (int)dataGridViewStmt.CurrentRow.Cells[9].Value;
if (docID > 0)
{
getPDFFile(docID, pdfFile, "pdf");
}
else
{
MessageBox.Show("No invoice available for this item"; }
}
}
I called my bindGrid() method from the two place one after the InitializeComponent() in form's constructor as well as from form1_load(). it works for me.
hope this will also helps you.
I didn't get any replies here so I posted on another forum. I eventually got an answer of sorts, but the whole thing is still pretty vague. The answer I got stated that in order to preserve resources, the grid doesn't always refresh itself. An example is if you have a form with a tab control that has 2 tabs, place a grid on the 1st tab and set column properties after binding in Form Load. This will work. However, when you place the grid on the 2nd tab, using the same binding won't work:
http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/99ab9fbf-9eaa-4eef-86b8-8f4e49fa81c5
I still haven't found out how or when it decides to preserve resources, if there's a way to bypass this behaviour, if this behaviour is documented anywhere etc. If anyone can throw more light on it I'm all ears.
I had the very same issue. I originally had a DataGridView on a separate form and it worked perfectly with the button column - which I add in code after setting the datasource. However, when I decided to move the grid onto another form with a Tabbed Control (on to the Tab(2) page as it happens), the button column index kept reverting to zero. It looked perfectly OK on the grid of course, i.e. in the correct physical location, and if I stepped through the code in debug mode the Index didn't change, but when I ran the program it did change! Very frustrating.
I solved it by setting the tab page to the page that my grid was located BEFORE setting the datasource.
My simple process was like this (I use VB10):
TabControl1.SelectedIndex = 2 ' this is where the datagridview is
MyGrid.DataSource = Nothing
MyGrid.Columns.Clear
' I execute an Sql command into a DataReader, then fill a DataTable and then assign it to the grid
MyGrid.DataSource = MyDataTable
' Now add button column
Dim btnCol as New DatGridViewButtonColumn
MyGrid.Columns.Add(btnCol)

Resources