Devexpress Reporting get Row data by click in it - c#

I try get all values from the row(where was click) of XtraReport.
I don't know why, but xrTableRow1_PreviewClick and xrTable1_PreviewClick don't work.
Works only xrTableCell4_PreviewClick. And through 'e.Brick.Text' I can get only value in cell.
private void xrTableCell1_PreviewClick(object sender, PreviewMouseEventArgs e)
{
var tmp = e.Brick.Text;
}
If I try:
GetCurrentRow()
It gives only first row. It's not what I need. )
How can I get all values from the row where was click? Or how I can get Row Index where click was?
My report looks like in designer:
Thanks in advance!

There is no simple way to access the corresponding data row using brick methods. When all the required bricks are generated, the report does not refer to a data source anymore. In other words, bricks do now know about the underlying data. They just contain a text, image, or other controls.
The simplest way to accomplish this task is to handle the XRControl's BeforePrint event and pass the corresponding data object (DataRowView or a custom object) to the XRControl's Tag property:
private void xrLabel_BeforePrint(object sender, System.Drawing.Printing.PrintEventArgs e) {
// Obtain the current label.
XRLabel label = (XRLabel)sender;
//Obtain the parent Report
XtraReportBase parentReport = label.Report;
//Get the data object
object currentData = parentReport.GetCurrentRow();
//Pass this object to Tag
label.Tag = currentData;
}
After that, it's possible to access the data object via the e.Brick.Value property in the PreviewClick event handler.

VB.net code to capture the values of any field in detail bank in preview mode.
Dim myo As Object
dim myacct as long
For i = 0 To e.Brick.Parent.Bricks.Count
Try
myo = e.Brick.Parent.Bricks.Item(i) ' cant get name w/o this ???
If myo.brickowner.name = "XrLabel14" Then ' test for desired label
myacct = myo.text 'capture the value
Exit For
End If
Catch oerr As Exception
'log error here
End Try
Next

Related

ObjectListView editing doesn't work

I'm trying to create a simple listbox with ObjectListView (WinForm, C#). The goal is to have a single value (a double) and a check box.
I want to be able to edit the double value by Single Click, so here are the relevant lines of code from my MyWindow.Designer.cs file (i've left out the default values for efficiency):
this.olvDepths = new BrightIdeasSoftware.ObjectListView();
this.olvColumn1 = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
...
this.olvDepths.CellEditActivation = BrightIdeasSoftware.ObjectListView.CellEditActivateMode.SingleClick;
this.olvDepths.CheckBoxes = true;
this.olvDepths.CheckedAspectName = "IsDefault";
this.olvDepths.FullRowSelect = true;
//
// olvColumn1
//
this.olvColumn1.AspectName = "Depth";
this.olvColumn1.Text = "";
this.olvColumn1.IsEditable = true;
I then create a list of my class (ShieldingEntry) and use the olvDepths.SetObjects() with the list. My ShieldingEntry class looks like this:
public class ShieldingEntry
{
public double Depth { get; set; }
public bool IsDefault { get; set; }
}
However, when I click the field, it doesn't go into edit mode. I've also tried the DoubleClick, SingleClickAlways, and F2Only modes and they don't work either.
The Checkbox works fine.
************** I have additional information *********************
I've pulled and build the ObjectListView source, so I could step through it.
I put a breakpoint in the OLV StartCellEdit method and it gets called and appears to setup and select the control appropriately. It just never appears...
As I noted in the comments on the answer below, I've got this control on a tabbed dialog, and if I switch to another tab, then back, the control works fine.
What am I missing?
I've used ObjectListView before, and here is what I had to do:
Handle the CellEditStarting event. This event is raised when the cell goes into edit mode. Since OLV doesn't really have built-in editors, you have to make your own. Then handle the CellEditFinishing event to validate the data before putting it back into your model.
So first, handling the CellEditStarting event:
private void objlv_CellEditStarting(object sender, CellEditEventArgs e)
{
//e.Column.AspectName gives the model column name of the editing column
if (e.Column.AspectName == "DoubleValue")
{
NumericUpDown nud = new NumericUpDown();
nud.MinValue = 0.0;
nud.MaxValue = 1000.0;
nud.Value = (double)e.Value;
e.Control = nud;
}
}
This creates your editing control. If you want to make sure the size is right, you can set the size of the control (in this case a NumericUpDown) to the cell bounds using e.CellBounds from the event object.
This will show the editor when you click in the cell. Then you can handle the editor finished event to validate the data:
private void objlv_CellEditFinishing(object sender, CellEditEventArgs e)
{
if (e.Column.AspectName == "DoubleValue")
{
//Here you can verify data, if the data is wrong, call
if ((double)e.NewValue > 10000.0)
e.Cancel = true;
}
}
I don't think handling it is required, but its good practice to validate data from the user.
The editing control in the CellEditStarting event can be any control, even a user defined one. I've used a lot of user defined controls (like textboxes with browse buttons) in the cell editor.
[Edit]
I uploaded an example here dropbox link that seems to work. Might not be in the exact view as needed, but seems to do the job.
For anyone else with this problem. I had it specifically when trying to edit a 'null' value in a decimal? on the OLV on a tab page. Solution for me was to set UseCustomSelectionColors to 'False'. I didn't look elsewhere to see if it was reported as a bug. Seems like a bug.

Select one string line in a list

I'm trying to simply select one string line out a long list strings that are held on a server and seperated with a pipe character. This string is grabbed by a php script and the string line is a list of all the media and folders I have on my server.
In my code I'm getting this information and returning it with the following code:
using (var client = new WebClient())
{
result = client.DownloadString("http://server.foo.com/images/getDirectoryList.php");
}
textBox1.Text = string.Join(Environment.NewLine, result.Split('|'));
And it looks like this:
But when I try to simply click on one of them, my cursor simply just goes to where I've clicked. Like this, I tried to select md-harrier.jpg and my cursor just ends up at the end of jpg:
What I'm really wanting is pictured below. I click on Koala.jpg and the whole thing is highlighted and I have the ability to store the name of what it is I've just clicked on. TO achieve that screen shot I had to click next to Koala.jpg and then drag my mouse along.
Is there anyway I can achieve what I want to achieve?
The key thing to note about this is that I will have no idea how many files will be on the server, nor what they will be called. My php script is grabbing this information and displaying it in my winform text box using the code I have wrote above.
as Simon said you need a ListBox, a ListBox fits here because it allows you to select a line, and you can register to the event of SelectedIndexChanged and store the name that was selected.
to initiate the values do
using (var client = new WebClient())
{
result = client.DownloadString("http://bender.holovis.com/images/getDirectoryList.php");
}
listBox1.Items.AddRange(result.Split('|'));
listBox1.SelectedIndexChanged += new System.EventHandler(this.listBox1_SelectedIndexChanged);
and on the selectedItemChanged:
string currVal;
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
currVal = (string)listBox1.SelectedItem;
}
As you said you have no reason to use TextBox,then by using ListBox you can achieve that in this way;
using (var client = new WebClient())
{
result = client.DownloadString("http://bender.holovis.com/images/getDirectoryList.php");
}
string[] names=result.Split('|');
foreach(string name in names)
{
if(name!="|"&&name!=" ")
{
listbox.Items.Add(name);
}
}
Additionally,if you would like to store selected item in a variable subscribe to ListBox's SelectionChangedEvent and store the selection index in a variable in this way;
int selection=;
private void ListBox1_SelectionIndexChanged(object sender,EventArgs e)
{
selection=ListBox1.SelectedIndex;
}

Programatically change display of the sort icon in datagrid column header

I asked this question previously and did not get an answer but now I have more detail.
Basically I want to programatically display the column sort icon in a wpf datagrid column.
I have the following code to do this:
private void dtgMain_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
dtgMain.Columns[0].SortDirection = ListSortDirection.Ascending;
}
This seems to set the sort order of the column but when the grid is drawn the icon does not show.
When I add a message box into the method it works fine. My question is twofold. Why would the message box cause the method to work? And how can I get it to work without the use of a messagebox?
This is the method working with the messagebox in it:
private void dtgMain_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
MessageBox.Show("Here");
dtgMain.Columns[0].SortDirection = ListSortDirection.Ascending;
}
edit
Here is the method that is setting the datacontext of the datagrid
public void processLoad(string response)
{
XmlDataProvider provider = new XmlDataProvider();
if (provider != null)
{
System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
doc.LoadXml(response);
provider.Document = doc;
provider.XPath = "/moo/response/data/load/panel";
dtgMain.DataContext = provider;
}
}
Please let me know if you need anymore information.
OK, I suspect what is happening is that the data layout changes caused by the DataContext update are being completed after your call to set the direction arrow, and it is therefore being erased after you set it. Interestingly, in my case it failed to work even when I put the messagebox in, perhaps because that was hanging up the UI thread while it displayed.
Could you try replacing the line that sets the sort direction with a similar call put on the dispatcher queue:
dtgMain.Dispatcher.BeginInvoke(new Action(() =>
{
dtgMain.Columns[0].SortDirection = ListSortDirection.Ascending;
}), DispatcherPriority.ApplicationIdle);
and see if that works?

Populating a form’s textbox with data from a second form

The application has two forms. The main form (Form#1) utilizes threading. One of these threads is used for reading in parameters from a TCP/IP socket. Once the value of one specific parameter has changed, I want to display this new value in a textbox on the second form (Form#2).
I have listed what I believe to be the significant parts of the code below.
Form#1:
//Resetting the manually adjusted 'gusBundlesPlacedOnPallet' parameter
if (gusBundlesInRow > 0)
{
gusBundlesInRow = 0;
//Update the 'BundlesOnPallet' display on the 'Manual Page' frmManualMode ManualMode = new frmManualMode();
ManualMode.NoOfBundlesInPalletizerDisplay(Convert.ToString(iIncomingMsg[15]));
}//End-if
Form#2:
//Creating a NoOfBundlesInPalletizer Delegate
public delegate void NoOfBundlesInPalletizerDisplayDelegate(string sMessage);
public void NoOfBundlesInPalletizerDisplay(string sMessage)
{
if (txtBundlesInPalletizer.InvokeRequired)
{
Invoke(newNoOfBundlesInPalletizerDisplayDelegate(NoOfBundlesInPalletizerDisplay), new object[] { sMessage });
}//End-if
else
{
this.txtBundlesInPalletizer.Text = sMessage;
}//End else-if
}//End method NoOfBundlesToPalletizeDisplay
The textbox on Form#2 will not show the new value, although if I insert a break point just after I have assign the new value to the textbox (sMessage), it does contain the correct value.
Additionally, if I close the second form and then reopen it, it will show the correct value. It looks to me that I need some kind of “refresh” of the textbox value?
Can anyone tell me what I’m doing wrong?
Thanks in advance
Terje
In my experience Control elements are always automatically updated. But you could try Control.Refresh();

How can I set the position of my datagrid scrollbar in my winforms app?

In my C# winforms app, I have a datagrid. When the datagrid reloads, I want to set the scrollbar back to where the user had it set. How can I do this?
EDIT: I'm using the old winforms DataGrid control, not the newer DataGridView
You don't actually interact directly with the scrollbar, rather you set the FirstDisplayedScrollingRowIndex. So before it reloads, capture that index, once it's reloaded, reset it to that index.
EDIT: Good point in the comment. If you're using a DataGridView then this will work. If you're using the old DataGrid then the easiest way to do that is to inherit from it. See here: Linkage
The DataGrid has a protected GridVScrolled method that can be used to scroll the grid to a specific row. To use it, derive a new grid from the DataGrid and add a ScrollToRow method.
C# code
public void ScrollToRow(int theRow)
{
//
// Expose the protected GridVScrolled method allowing you
// to programmatically scroll the grid to a particular row.
//
if (DataSource != null)
{
GridVScrolled(this, new ScrollEventArgs(ScrollEventType.LargeIncrement, theRow));
}
}
Yep, definitely FirstDisplayedScrollingRowIndex. You'll need to capture this value after some user interaction, and then after the grid reloads you'll want to set it back to the old value.
For instance, if the reload is triggered by the click of a button, then in the button click handler, you might want to have as your first line a command that places this value into a variable:
// Get current user scroll position
int scrollPosition = myGridView.FirstDisplayedScrollingRowIndex;
// Do some work
...
// Rebind the grid and reset scrolling
myGridView.DataBind;
myGridView.FirstDisplayedScrollingRowIndex = scrollPosition;
Store your vertical and horizontal scroll values into some variable and reset them.
int v= dataGridView1.VerticalScrollingOffset ;
int h= dataGridView1.HorizontalScrollingOffset ;
//...reload
dataGridView1.VerticalScrollingOffset = v;
dataGridView1.HorizontalScrollingOffset =h;
you can save scroll position with next code
int Scroll;
void DataGridView1Scroll(object sender, ScrollEventArgs e)
{
Scroll = dataGridView1.VerticalScrollingOffset;
}
and you can set scroll of dgv to same position after refresing, load dgv... with next code:
PropertyInfo verticalOffset = dataGridView1.GetType().GetProperty("VerticalOffset", BindingFlags.NonPublic |
BindingFlags.Instance);
verticalOffset.SetValue(this.dataGridView1, Scroll, null);
Just posted the answer on the link given by BFree
The DataGrid has a protected GridVScrolled method that can be used to scroll the grid to a specific row. To use it, derive a new grid from the DataGrid and add a ScrollToRow method.
C# code
public void ScrollToRow(int theRow)
{
//
// Expose the protected GridVScrolled method allowing you
// to programmatically scroll the grid to a particular row.
//
if (DataSource != null)
{
GridVScrolled(this, new ScrollEventArgs(ScrollEventType.LargeIncrement, theRow));
}
}
VB.NET code
Public Sub ScrollToRow(ByVal theRow As Integer)
'
' Expose the protected GridVScrolled method allowing you
' to programmatically scroll the grid to a particular row.
'
On Error Resume Next
If Not DataSource Is Nothing Then
GridVScrolled(Me, New ScrollEventArgs(ScrollEventType.LargeIncrement, theRow))
End If
End Sub
I used the answer by #BFree, but also needed to capture the first visible row in the DataGrid:
int indexOfTopMostRow = HitTest(dataGrid.RowHeaderWidth + 10,
dataGrid.PreferredRowHeight + 10).Row;
Even though this is an old question, Many of the solutions above did not work for me. What worked ultimately was:
if(gridEmployees.FirstDisplayedScrollingRowIndex != -1) gridEmployees.FirstDisplayedScrollingRowIndex = 0;

Categories

Resources