Hello I'm trying to show a legend in runtime but for some kind of reason it won't show up or the complete size of my chart changes but still I don't see the legend.
Here is the part of the code that draws the Chart
foreach (DataGridViewRow row in dataGridView1.Rows)
{
TempDate = Convert.ToDateTime(row.Cells[0].Value);
if (row.Cells[1].Value.ToString().Equals(SelectedSpeed))
{
//Get vibration values
yHDE = Convert.ToDouble(row.Cells[2].Value, CultureInfo.InvariantCulture);
//Plot Horizontal DE chart
if (yHDE != 0)
{
if (MachineName == newMachineName)
{
//Draw the points in the selected series
this.chartHorizontalDE.Series[MachineName].Points.AddXY(TempDate, yHDE);
}
else if (MachineName != newMachineName)
{
//When a new machine has been selected create a new series name for the chart
this.chartHorizontalDE.Series.Add(newMachineName);
this.chartHorizontalDE.Series[newMachineName].ChartType = SeriesChartType.Line;
}
}
}
Legend legend = new Legend();
legend.Docking = Docking.Right;
chartHorizontalDE.Legends.Add(legend);
}
I believe I have all the info in my code and the series for the particular chart should be available. The above last three lines finally gave a result but just changing the size of the chart and I was not able to see the legend. The example on MSDN gave me error that the particular series allready existed btw. I have deleted a big part of the code so maybe I do certain things like it is here is because there is more code but not relevant for the question (I think).
Where do I make a mistake?
Related
I am looping through each item in a listview and formatting the text boxes in the grid view. The initial format works, but then formatting disappears if I scroll the listview up and down a couple of times.
This is the basic loop to work through my items:
for (int i = 0; i < lvDocumentation.Items.Count; i++)
{
// Grabs the item
ListBoxItem selectedListBoxItem = lvDocumentation.ItemContainerGenerator.ContainerFromItem(lvDocumentation.Items[i]) as ListBoxItem;
PersonDTO thisPersonDTO = (PersonDTO)lvDocumentation.Items[i];
// I do some odds and ends here and call formatting routines for the buttons...
}
Later after I do some checking on thisPersonDTO, I format the selectedListBoxItem depending on the persons status
// Textblock
foreach (var item in UiCommon.FindVisualChildren<TextBlock>(selectedListBoxItem))
{
if (item.Name.ToLower() == textblockName.ToLower())
{
if (docPresent)
{
//item.Background = backgroundColor;
item.Foreground = Brushes.Green;
}
else
{
((TextBlock)item).Foreground = Brushes.Red;
}
}
}
// Button
foreach (var item in UiCommon.FindVisualChildren<Button>(selectedListBoxItem))
{
if (item.Name.ToLower() == buttonName.ToLower())
{
if (item.GetType().Name == "Button")
{
if (docPresent)
{
//item.Background = backgroundColor;
item.IsEnabled = true;
}
else
{
//item.Background = backgroundColor;
((Button)item).IsEnabled = false;
}
}
}
}
That code works and the formatting is done correctly (as long as the listBoxItem is in the display, but that's another story)
Once the process is completed button colors are set.
If I scroll up and down a bit the colors revert to their original formatting and I can't figure out why. I have breakpoints everywhere, but don't see any code executing.
I realize that there are formatting issues when I try to format listboxitems that are not yet displayed. I use this bit of code for that:
lvDocumentation.UpdateLayout();
lvDocumentation.ScrollIntoView(lvDocumentation.Items[index]);
selectedListBoxItem = lvDocumentation.ItemContainerGenerator.ContainerFromItem(lvDocumentation.Items[index]) as ListBoxItem;
That gets me the listbox item rather than null if the item originally returned null because it was not in the display area.
Something seems to be refreshing the formatting, but no clue why / where?
If I scroll up and down a bit the colors revert to their original formatting and I can't figure out why.
It's because of the default UI virtualization and container recycling that is described in the docs.
You may disable the virtualization by setting the attached IsVirtualizing property to false:
VirtualizingPanel.SetIsVirtualizing(lvDocumentation, false);
This comes at the expense of the scrolling performance but given your current approach of manipulating the UI containers directly, that's your only option.
You should look into MVVM. It's the recommended design pattern to use when developing XAML based UI applications.
We have Word Interop based process in place to generate invoices. This process, which runs for years, loads a pre-built docx template file and populates with the data. Both header and footer of that template have a table each. Currently the code below populates the text in a given cell of the footer
protected override void OnEnterRow()
{
Try(() => _parent.OLE_WordCell.Value = _parent.OLE_WordTable.Value.Cell(u.ToInt(I_RowNumber), u.ToInt(I_CellNumber)));
Try(() => _parent.OLE_WordCell.Value.Range.Text = u.TrimEnd(I_CellText));
Try(() => _parent.OLE_WordCell.Value.Range.Font.Bold = u.ToInt(I_CellBold));
}
I need to add an image to the footer of the invoice, based on a certain, simple logic. I have seen multiple examples on this and other sites how to do it. Though in my case it does add the image, but not in the footer and I will much appreciate any help.
Before doing any significant change, I wanted to simply show the image instead of the text, so I have disabled the lines above and applied the following code:
Try(() => _parent.OLE_WordCell.Value = _parent.OLE_WordTable.Value.Cell(u.ToInt(I_RowNumber), u.ToInt(I_CellNumber)));
Try(() => _parent.OLE_WordCell.Value.Range.InlineShapes.AddPicture(I_FilePath).ConvertToShape());
It added the image in a middle of the invoice (NOT the footer). Since I have tried various codes and below is the latest, but to no avail.
This code placed one big image all over the invoice
var _cell = _parent.OLE_WordTable.Value.Cell(u.ToInt(I_RowNumber), u.ToInt(I_CellNumber));
var _range = _cell.Range;
var _shape = _range.InlineShapes.AddPicture(I_FilePath.Value.ToString().Trim()).ConvertToShape();
so I have added height and width:
var _cell = _parent.OLE_WordTable.Value.Cell(u.ToInt(I_RowNumber), u.ToInt(I_CellNumber));
var _range = _cell.Range;
var _shape = _range.InlineShapes.AddPicture(I_FilePath.Value.ToString().Trim()).ConvertToShape();
_shape.HeightRelative = 8f;
_shape.WidthRelative = 10f;
It succeeded to reduce the size, but the image remained in a middle of the invoice. Then I have added Select() as I have seen someone advised. But that placed the image in the left top corner of the page.
var _cell = _parent.OLE_WordTable.Value.Cell(u.ToInt(I_RowNumber), u.ToInt(I_CellNumber));
_cell.Select();
var _range = _cell.Range;
var _shape = _range.InlineShapes.AddPicture(I_FilePath.Value.ToString().Trim()).ConvertToShape();
_shape.HeightRelative = 8f;
_shape.WidthRelative = 10f;
Anything else I shall try, please?
I am using Xamarin and C# but I suspect the problem is equally valid in a Java environment.
I have an ActionBar Activity that hosts three tabs each of which hosts a fragment. It uses a ViewPager to allow the user to swipe between the tabs.
The requirement is to programmatically screenshot each tab and then email these as attachments.
The problem is that whilst the ActionBar/ViewPager works well it also optimises the tabs - effectively it isn't creating a fragment's view until it is next in line to be shown. So, if you're on tab 0 - the first tab - then the fragment view for tab 2 is null. So it can't be screenshot.
To overcome this I have tried to set any tab/fragment that has a null view to be selected. This generates the view but because setting it to be selected does not actually render it on screen the view does not have a width or a height value so again it cannot be screenshot (this is the reason for the defensive check at the start of the code taking the screenshot).
So, I guess my question is how can I force the tab to be rendered on screen so that it is correctly filled out and can be screenshot?
My main code extracts are as follows:
private void EmailReport()
{
List <Bitmap> bitmaps = new List<Bitmap>();
List <string> summaryFiles = new List<string>();
// remember the tab we're on
var selectedTab = this.ActionBar.SelectedNavigationIndex;
// take the screenshots
for (int fragmentNumber = 0; fragmentNumber < projectFragmentPagerAdapter.Count; fragmentNumber++)
{
Android.Support.V4.App.Fragment fragment = projectFragmentPagerAdapter.GetItem(fragmentNumber);
if (fragment.View == null)
{
this.ActionBar.GetTabAt(fragmentNumber).Select();
fragment = projectFragmentPagerAdapter.GetItem(fragmentNumber);
}
bitmaps.Add(ScreenShot(fragment.View));
}
// set the active tab back
this.ActionBar.GetTabAt(selectedTab).Select();
//write the screenshots into file
int i = 0;
foreach(Bitmap bitmap in bitmaps)
{
if (bitmap != null)
summaryFiles.Add(BitmapToFile(bitmap, this.ActionBar.GetTabAt(i).Text));
i++;
}
// now send the file
EmailSupport.SendAttachments(this, summaryFiles);
}
private Bitmap ScreenShot(View fragmentRootView)
{
if (fragmentRootView == null || fragmentRootView.Width == 0 || fragmentRootView.Height == 0)
return null;
fragmentRootView.DrawingCacheEnabled = true;
//create a bitmap for the layout and then draw the view into it
Bitmap bitmap = Bitmap.CreateBitmap(fragmentRootView.Width, fragmentRootView.Height,Bitmap.Config.Argb8888);
Canvas canvas = new Canvas(bitmap);
//Get the view's background
Drawable bgDrawable = fragmentRootView.Background;
if (bgDrawable!=null) // has background drawable, then draw it on the canvas
bgDrawable.Draw(canvas);
else // does not have background drawable, then draw white background on the canvas
canvas.DrawColor(Color.White);
// draw the view on the canvas
fragmentRootView.Draw(canvas);
fragmentRootView.DrawingCacheEnabled = false;
return bitmap;
}
Any help would be gratefully received.
The solution in the end was very simple. The ViewPager has a setting controlling the number of pages (fragments) that it will hold "activated". This defaults to 1. As I had 3 tabs this meant there was always one tab (fragment) out of reach.
So, whilst setting up the ViewPager do the following before the tabs are added:
reportViewPager.OffscreenPageLimit = pageCount - 1;
Or in Java
reportViewPager.setOffscreenPageLimit(pageCount - 1);
I hope this helps someone else avoid wasting hours.
I would like to display something if the data grid View is long and showing a scroll bar but don't know how to check if the scroll bar is visible. I can't simply add the rows since some may be not visible. I can't use an event since my code is already in an event.
you can try this out:
foreach (var scroll in dataGridView1.Controls.OfType<VScrollBar>())
{
//your checking here
//specifically... if(scroll.Visible)
}
I prefer this one :
//modif is a modifier for the adjustment of the Client size of the DGV window
//getDGVWidth() is a custom method to get needed width of the DataGridView
int modif = 0;
if (DataGridView.Controls.OfType<VScrollBar>().First().Visible)
{
modif = SystemInformation.VerticalScrollBarWidth;
}
this.ClientSize = new Size(getDGVWidth() + modif, [wantedSizeOfWindow]);
so the only Boolean condition you need is:
if (DataGridView.Controls.OfType<VScrollBar>().First().Visible)
{
//want you want to do
}
The DataGridView's Scrollbars Property can be questioned using the ScrollBars Enumeration by masking it with the one you are interested in like this:
if ((dataGridView1.ScrollBars & ScrollBars.Vertical) != ScrollBars.None) ...
Note, that the two 'ScrollBars' are different things here!
The answer from terrybozzio works only if you use the System.Linq namespace.
A solution without using System.Linq is shown below:
foreach (var Control in dataGridView1.Controls)
{
if (Control.GetType() == typeof(VScrollBar))
{
//your checking here
//specifically... if (((VScrollBar)Control).Visible)
}
}
To determine if the vertical scrollbar is present, you need to check how tall your visible rows are and compare against the datagridview height.
if(dgv1.Height > dgv1.Rows.GetRowsHeight(DataGridViewElementStates.Visible))
{
// Scrollbar not visible
}
else
{
// Scrollbar visible
}
Though to be more exact you may need to include a check of column widths as the presence of a horizontal scrollbar could create a vertical scrollbar that otherwise isn't there.
I want to insert text from TextBox in a word document using c# and spire.dll tools, but when I using code FillEffects not worked same this code
textBox.Format.FillEfects.Gradient.Color1 = Color.Red;
textBox.Format.FillEfects.Gradient.Color2 = Color.Yellow;
textBox.Format.FillEfects.Gradient.ShadingStyle = GradientShadingStyle.DiagonalUp;
The code is correct and my program is build correct, but it not make any changes for textBox and if I want to fill effect with picture it not worked else Like this code
textBox.Format.FillEfects.Picture = pictureBox1.Image;
I Attach To you My small project to see why this code not worked
Okay after trying to fix this for a few hours i figured it out. I have slightly re-coded your textbox but don't worry. I added comments. I worked hard on this one. The answer though, was quite simple. I have never used Spire so I had to learn as I went.
//Creates gradient
Spire.Doc.BackgroundGradient myGradient = new BackgroundGradient();
myGradient.Color1 = Color.Red;
myGradient.Color2 = Color.Yellow;
myGradient.ShadingStyle = GradientShadingStyle.DiagonalUp;
myGradient.ShadingVariant = GradientShadingVariant.ShadingDown;
//Insert TextBox
Paragraph paragraph1 = section.AddParagraph();
Spire.Doc.Fields.TextBox textBox = paragraph1.AppendTextBox(200, 100);
textBox.Format.LineColor = Color.DeepSkyBlue;
textBox.Format.LineWidth = 3.5F;
textBox.Format.LineStyle = TextBoxLineStyle.Double;
//Sets the gradient you made
textBox.Format.FillEfects.Gradient = myGradient;
//Sets the textbox to USE the gradient
textBox.Format.FillEfects.Type = BackgroundType.Gradient;
Please add below code to your program before setting the textBox fill effect.
textBox.Format.FillEfects.Type = BackgroundType.Gradient;
E-iceblue Support team.