Unity Editor - Displaying GUI lines between two points using switch case - mono

I am trying to implement an editor script that would display GUI lines between any two points in the editor. I have three empty game objects as Vector3 points (A, B and C), and for example, if button #1 is pressed, a value of integer "switchCase" will be set to 1, and according to the switch case statement, it will display a line between point A and point B. If button #2 is pressed, "switchCase" is set to 2, and it will display lines between point A and B, and between point B and C, and so on.
The problem I have is that when I press the buttons - nothing happens in the editor. I can see that the value of "switchCase" is changing correctly in the inspector, but the lines are not showing.
If I input the value straight in the inspector, it works as it should, but my goal is to have the value changing when the button is pressed, rather that me changing the value in the inspector manually.
Hopefully my question makes sense. Any help will be appreciated!
Here is the Editor script:
using UnityEngine;
using System.Collections;
using UnityEditor;
using System.Collections.Generic;
using UnityEditor.AnimatedValues;
using System.Linq;
[CustomEditor(typeof(LineTest))]
public class LineTestInspector : Editor
{
public LineTest myScript;
public void OnSceneGUI()
{
Handles.color = Color.red;
switch (myScript.switchCase)
{
case 1:
GameObject posAobj = GameObject.Find("PointA");
GameObject posBobj = GameObject.Find("PointB");
myScript.posA = posAobj.transform.position;
myScript.posB = posBobj.transform.position;
Handles.DrawLine(myScript.posA, myScript.posB);
break;
case 2:
GameObject posCobj = GameObject.Find("PointC");
myScript.posC = posCobj.transform.position;
Handles.DrawLine(myScript.posA, myScript.posB);
Handles.DrawLine(myScript.posB, myScript.posC);
break;
}
public override void OnInspectorGUI()
{
DrawDefaultInspector();
if (GUILayout.Button("Draw First Line"))
{
myScript.switchCase= 1;
Debug.Log("Switch - 1");
}
if (GUILayout.Button("Draw Second Line"))
{
myScript.switchCase = 2;
Debug.Log("Switch - 2");
}
if (GUILayout.Button("Reset switchCase"))
{
myScript.switchCase = 0;
Debug.Log("Switch - 0");
}
}
}
And the Mono script:
using System.Collections;
using System;
using System.Collections.Generic;
using UnityEngine;
public class LineTest : MonoBehaviour {
public Vector3 posA;
public Vector3 posB;
public Vector3 posC;
public int switchCase;
}

You have to call EditorUtility.SetDirty(myScript); for the Editor to update after changing the values.
Your code should look like this:
public override void OnInspectorGUI()
{
DrawDefaultInspector();
if (GUILayout.Button("Draw First Line"))
{
myScript.switchCase = 1;
Debug.Log("Switch - 1");
EditorUtility.SetDirty(myScript);
}
if (GUILayout.Button("Draw Second Line"))
{
myScript.switchCase = 2;
Debug.Log("Switch - 2");
EditorUtility.SetDirty(myScript);
}
if (GUILayout.Button("Reset switchCase"))
{
myScript.switchCase = 0;
Debug.Log("Switch - 0");
EditorUtility.SetDirty(myScript);
}
}

Related

Save and displaying high score with variable across classes unity

I need to get the variable score from my other class and set it as a UserPrefs key. it doesnt seem to be setting as i have a GUI label ingame which shos "None" if there is no UserPrefs key "Highscore".
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Threading;
public class Player : MonoBehaviour {
public Vector2 jumpForce = new Vector2(0, 300);
private Rigidbody2D rb2d;
Generator SwagScript;
GameObject generator;
// Use this for initialization
void Start () {
rb2d = gameObject.GetComponent<Rigidbody2D>();
generator = GameObject.FindGameObjectWithTag("Generator");
SwagScript = generator.GetComponent<Generator>();
}
// Update is called once per frame
void Update () {
if (Input.GetKeyUp("space"))
{
rb2d.velocity = Vector2.zero;
rb2d.AddForce(jumpForce);
}
Vector2 screenPosition = Camera.main.WorldToScreenPoint(transform.position);
if (screenPosition.y > Screen.height || screenPosition.y < 0)
{
Die();
}
}
void OnCollisionEnter2D(Collision2D other)
{
Die();
}
void Die()
{
if (PlayerPrefs.HasKey("HighScore"))
{
if (PlayerPrefs.GetInt("Highscore") < SwagScript.score)
{
PlayerPrefs.SetInt("HighScore", SwagScript.score);
}
else
{
PlayerPrefs.SetInt("HighScore", SwagScript.score);
}
}
Application.LoadLevel(Application.loadedLevel);
}
}
Unless you're creating the Highscore playerpref somewhere else, the Die() method won't never create it, since the if (PlayerPrefs.HasKey("HighScore")) will always return false.
Just remove that if.

Some rows are collapsed in DataGrid, I am getting issue in KeyBoard navigation

I am using DataGrid, run time i make visible collapse some rows.
Suppose my 4th row's visibility is collapse, and my focus is on 3rd row, when i try to move on 5th row with the help of Down-Arrow key, it is not working. Same way if my focus on 5th row and want to move on 3rd row with Up-Arrow key, it is also not working.
Now, what should i do?
This is actually a bug in .Net, there is a bug report here.
One workaround is to use Attached behavior to handle the up and down selection. The following example requires the IsSynchronizedWithCurrentItem to be set to true for the DataGrid.
Note! make sure you change the while condition to the appropriate way to determine if the item is collapsed.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Media;
namespace DataGridGroupingTest
{
class DataGridKeyboardNavigationAttachedBehavior
{
public static readonly DependencyProperty
KeyboardKey
= DependencyProperty.RegisterAttached(
"IsKeyboardNavigationEnabled",
typeof(bool),
typeof(DataGridKeyboardNavigationAttachedBehavior),
new PropertyMetadata(
false,
OnIsKeyboardNavigationEnabledChanged));
public static bool GetIsKeyboardNavigationEnabled(DependencyObject depObj)
{
return (bool)depObj.GetValue(KeyboardKey);
}
public static void SetIsKeyboardNavigationEnabled(DependencyObject depObj, bool value)
{
depObj.SetValue(KeyboardKey, value);
}
private static void OnIsKeyboardNavigationEnabledChanged(DependencyObject depObj, DependencyPropertyChangedEventArgs e)
{
DataGrid dataGrid = depObj as DataGrid;
if (dataGrid != null)
{
dataGrid.PreviewKeyDown += dataGrid_PreviewKeyDown;
dataGrid.IsSynchronizedWithCurrentItem = true;
}
}
static void dataGrid_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
{
DataGrid dataGrid = sender as DataGrid;
if (dataGrid != null && dataGrid.CurrentCell != null)
{
if (e.Key == System.Windows.Input.Key.Down || e.Key == System.Windows.Input.Key.Up)
{
ICollectionView view = CollectionViewSource.GetDefaultView(dataGrid.Items);
int loopCount = 0;
do
{
if (e.Key == System.Windows.Input.Key.Down)
{
view.MoveCurrentToNext();
if (view.IsCurrentAfterLast)
{
view.MoveCurrentToFirst();
loopCount++;
}
}
if (e.Key == System.Windows.Input.Key.Up)
{
view.MoveCurrentToPrevious();
if (view.IsCurrentBeforeFirst)
{
view.MoveCurrentToLast();
loopCount++;
}
}
} while (((Person)view.CurrentItem).Boss != null && !((Person)view.CurrentItem).Boss.IsExpanded && loopCount < 2);
// We have to move the cell selection aswell.
dataGrid.CurrentCell = new DataGridCellInfo(view.CurrentItem, dataGrid.CurrentCell.Column);
e.Handled = true;
return;
}
}
}
}
}

Telerik Mail Merge - Friendly Names (using RadRichTextBox)

I think i'm missing something obvious...
I'm using the Telerik Rad controls for WPF but i assume that the Rich text box uses some similar implementation for the mail merge functionality.
I want to have some friendly names on my mail merge fields. (namely spaces in the field names)
So i have a class for instance
Public Class someclass
{
<DisplayName("This is the complex description of the field")>
Public property thisfieldnamehasacomplexdescription as string
Public property anothercomplexfield as string
}
This is the only way i know to get "Friendly" names in the dropdown that is the mail merge.
So the two fields turn up okay as :
"This is the complex description of the field"
"anothercomplexfield"
but only anothercomplexfield actually populates with data when you do the merge.
Am i going to have to template the raddropdownbutton that holds the mail merge fields?
Is there an example of this somewhere?
Also a sub question. How do i add a scroll bar on these things?
(also i know this board is not a TELERIK specific board (duh!) but this might be useful to someone in the future. So i'll copy the answer i get from Telerik into here!
http://www.telerik.com/community/forums/wpf/richtextbox/558428-radrichtextbox-mailmerge---using-displayname-to-create-a-friendly-name-with-spaces.aspx )
This is what telerik gave me:
With the default MergeFields, it is not possible to change the display name fragment of the field in order to achieve a more friendly look. This should be possible if you implement a custom MergeField by deriving from the MergeField class. Here is a sample implementation that shows how this can be done:
public class CustomMergeField : MergeField
{
private const string CustomFieldName = "CustomField";
static CustomMergeField()
{
CodeBasedFieldFactory.RegisterFieldType(CustomMergeField.CustomFieldName, () => { return new CustomMergeField(); });
}
public override string FieldTypeName
{
get
{
return CustomMergeField.CustomFieldName;
}
}
public override Field CreateInstance()
{
return new CustomMergeField();
}
protected override DocumentFragment GetDisplayNameFragment()
{
return base.CreateFragmentFromText(string.Format(Field.DisplayNameFragmentFormat, this.GetFriendlyFieldName(this.PropertyPath)));
}
private string GetFriendlyFieldName(string fieldName)
{
int lettersInEnglishAlphabet = 26;
List<char> separators = new List<char>(lettersInEnglishAlphabet);
for (int i = 0; i < lettersInEnglishAlphabet; i++)
{
separators.Add((char)('A' + i));
}
StringBuilder newFieldName = new StringBuilder();
int previousIndex = 0;
for (int i = 1; i < fieldName.Length; i++)
{
if (separators.Contains(fieldName[i]))
{
if (previousIndex > 0)
{
newFieldName.Append(" ");
}
newFieldName.Append(fieldName.Substring(previousIndex, i - previousIndex));
previousIndex = i;
}
}
newFieldName.Append(" " + fieldName.Substring(previousIndex));
return newFieldName.ToString();
}
}
Note that the fragment that is shown when the DisplayMode is Code cannot be changed.
As for your other question, you can change the content of the dropdown button to show the friendly name of the fields and to include a scrollbar in the following way:
1. First, remove the binding of the button to the InsertMergeFieldEmptyCommand from XAML and give it a name (e.g. insertMergeField).
2. Next, add the following code in code-behind:
AddMergeFieldsInDropDownContent(this.insertMergeFieldButton);
private void AddMergeFieldsInDropDownContent(RadRibbonDropDownButton radRibbonDropDownButton)
{
Grid grid = new Grid();
grid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(100, GridUnitType.Pixel) });
ScrollViewer scrollViewer = new ScrollViewer();
scrollViewer.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
StackPanel stackPanel = new StackPanel();
foreach (string fieldName in this.editor.Document.MailMergeDataSource.GetColumnNames())
{
RadRibbonButton fieldButton = new RadRibbonButton()
{
Text = this.GetFriendlyFieldName(fieldName),
Size = ButtonSize.Medium,
HorizontalAlignment = HorizontalAlignment.Stretch,
HorizontalContentAlignment = HorizontalAlignment.Left
};
fieldButton.Command = this.editor.Commands.InsertFieldCommand;
fieldButton.CommandParameter = new MergeField() { PropertyPath = fieldName };
//or
//fieldButton.CommandParameter = new CustomMergeField() { PropertyPath = fieldName };
stackPanel.Children.Add(fieldButton);
}
stackPanel.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
scrollViewer.Content = stackPanel;
grid.Children.Add(scrollViewer);
radRibbonDropDownButton.DropDownContent = grid;
}
You can, of course optimize the code of the GetFriendlyName method and add it in a way that will be available by both classes.

Application crashes when launching an event only in MonoTouch 4.0.1

I have an application working under MonoTouch 3.2.6;
the same application, under MonoTouch 4.0.1, crashes when launching any touch event.
Reading another question, at source, I understand that the problem lies in an object collected from the GC, but I can't see which one is. The application starts and loads dinamically the TabBar, but clicking on any TabItem crashes the app. The files main.cs and TabDelegate.cs are listed below: Main.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
using System.Drawing;
using IPadApp.Classes;
using AggiornamentiCL;
namespace VSViewer
{
public class Application
{
static void Main (string[] args)
{
UIApplication.Main (args);
}
}
// The name AppDelegate is referenced in the MainWindow.xib file.
public partial class AppDelegate : UIApplicationDelegate
{
public static UITabBar tabmain ;
public static UIViewController ctrMain;
public static Home ctrHome;
public static UIView viewMain;
public static WrapperMenu MenuManager;
public static WrapperValueStories ValueStoriesManager;
public static WrapperBibliography BibliographyManager;
public static WrapperStakeHolder StakeHolderManager;
public static Aggiornamento AggiornamentoManager;
public static string RegionId = "";
public static string RegionName= "";
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
// Reperisco il RegionName dai settings
RegionName= NSUserDefaults.StandardUserDefaults.StringForKey("regione");
// Inizializzo le variabili
tabmain = tabMain;
ctrMain = ctrmain;
viewMain = viewContent;
ctrHome = new Home(String.Empty, RegionName);
// Inizializzo i manager
MenuManager= new WrapperMenu();
ValueStoriesManager= new WrapperValueStories(ref viewMain);
BibliographyManager = new WrapperBibliography();
StakeHolderManager = new WrapperStakeHolder();
AggiornamentoManager = new Aggiornamento(ctrMain);
// Imposto i delegati
tabmain.Delegate = new TabDelegate(viewMain,
ctrMain,
MenuManager,
ValueStoriesManager,
BibliographyManager,
StakeHolderManager,
AggiornamentoManager);
// Reperisco il Root Menu
MenuManager.GetRootMenu(ref tabmain);
if(string.IsNullOrEmpty(RegionName) || String.IsNullOrEmpty(Utils.GetRegionIDByName(RegionName)))
MenuManager.SoloRegioni(ref tabmain,false);
else
{
RegionId = Utils.GetRegionIDByName(RegionName);
Utils.LoadSplash(viewMain,"",RegionName);
}
// If you have defined a view, add it here:
window.AddSubview (ctrMain.View);
window.MakeKeyAndVisible ();
Thread tAggiornaDati = new Thread(new ThreadStart( Aggiornamento.AggiornaDati));
tAggiornaDati.Start();
return true;
}
}
}
TabDelegate.cs:
using System;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
using IPadApp.Classes;
using System.Collections.Generic;
using System.Linq;
using System.Drawing;
namespace VSViewer
{
public class TabDelegate : UITabBarDelegate
{
private WrapperMenu MenuManager;
private WrapperValueStories ValueStoriesManager;
private WrapperBibliography BibliographyManager;
private WrapperStakeHolder StakeHolderManager;
private Aggiornamento AggiornamentoManager;
private UIView viewMain;
//private UIViewController ctrmain;
private NodeAction previousAction ;
private int previousNode=0;
public TabDelegate (UIView pviewMain,
UIViewController pctrMain,
WrapperMenu pMenuManager,
WrapperValueStories pValueStoriesManager,
WrapperBibliography pBibliographyManager,
WrapperStakeHolder pStakeHolderManager,
Aggiornamento pAggiornamento)
{
viewMain = pviewMain;
MenuManager = pMenuManager;
ValueStoriesManager = pValueStoriesManager;
BibliographyManager= pBibliographyManager;
StakeHolderManager = pStakeHolderManager;
AggiornamentoManager = pAggiornamento;
}
private int GetSelectedTabBarIndex (UITabBar tabbar, UITabBarItem item)
{
for (int i = 0; i < tabbar.Items.Count (); i++) {
if (item == tabbar.Items[i])
return i;
}
return -1;
}
public override void ItemSelected (UITabBar tabbar, UITabBarItem item)
{
int itemSelectedIndex = GetSelectedTabBarIndex (tabbar, item);
MerqurioMenuNode currentNode = MenuManager.GetCurrentNodeByPos (itemSelectedIndex);
if (!(previousAction==currentNode.Action && previousNode == currentNode.MenuID) ||
currentNode.Action== NodeAction.OpenSubMenu)
{
// Rimuovo tutte le immagini della VS che sto abbandonando
if (previousAction== NodeAction.OpenValueStory) ValueStoriesManager.RemoveAllSlides();
// Detacho la View dell'azione precedente
foreach (UIView subView in this.viewMain.Subviews)
{
subView.RemoveFromSuperview ();
subView.Dispose();
}
// Mostro la view corretta
switch (currentNode.Action) {
case NodeAction.OpenSubMenu:
MenuManager.GetMenuByNodeId (ref tabbar, itemSelectedIndex);
// Imposto la breadcrumb
if (currentNode.ParentMenuID==0 && currentNode.Direction== NodeDirection.Forward) Breadcrumb.SetMolecola(currentNode.ViewLabel);
else if (currentNode.ParentMenuID==0 &&currentNode.Direction== NodeDirection.Backward) Breadcrumb.SetMolecola("");
Breadcrumb.UpdateBreadcrumb(currentNode.ViewLabel, AppDelegate.RegionName);
// Mostro la Splash
Utils.LoadSplash(viewMain,currentNode.ViewLabel,AppDelegate.RegionName);
break;
case NodeAction.OpenValueStory:
ValueStoriesManager.ShowValueStory (currentNode, AppDelegate.RegionId);
break;
case NodeAction.OpenBibliography:
BibliographyManager.ShowBibliography(viewMain,currentNode.FileName);
break;
case NodeAction.OpenStakeHolder:
StakeHolderManager.ShowStakeHolder(viewMain);
break;
case NodeAction.OpenRegion:
Regioni ctrRegioni = new Regioni();
this.viewMain.AddSubview(ctrRegioni.View);
break;
case NodeAction.OpenSimulator1:
Simulator_1 ctrSimulator1 = new Simulator_1();
this.viewMain.AddSubview(ctrSimulator1.View);
break;
case NodeAction.OpenSimulator2:
Simulator_2 ctrSimulator2 = new Simulator_2();
this.viewMain.AddSubview(ctrSimulator2.View);
break;
case NodeAction.OpenAggiornamento:
this.viewMain.AddSubview(AggiornamentoManager.View);
break;
default:
break;
}
}
// Aggiorno i contatori
previousAction = currentNode.Action;
previousNode = currentNode.MenuID;
}
}
}
Please help.. I can't found either the old file for MonoTouch 3.2.6...
When I look at your Main.cs file you have a pattern, except one of the things is reversed.
**tabmain = tabMain**;
ctrMain = ctrmain;
viewMain = viewContent;
I think you probably meant tabMain = tabmain;

ReportViewer - modify toolbar?

Do anyone have good ideas of how to modify the toolbar for the WinForms version of the ReportViewer Toolbar?
That is, I want to remove some buttons and varius, but it looks like the solution is to create a brand new toolbar instead of modifying the one that is there.
Like, I had to remove export to excel, and did it this way:
// Disable excel export
foreach (RenderingExtension extension in lr.ListRenderingExtensions()) {
if (extension.Name == "Excel") {
//extension.Visible = false; // Property is readonly...
FieldInfo fi = extension.GetType().GetField("m_isVisible", BindingFlags.Instance | BindingFlags.NonPublic);
fi.SetValue(extension, false);
}
}
A bit trickysh if you ask me..
For removing toolbarbuttons, an possible way was to iterate through the Control array inside the ReportViewer and change the Visible property for the buttons to hide, but it gets reset all the time, so it is not an good way..
WHEN do MS come with an new version btw?
Yeap. You can do that in a little tricky way.
I had a task to add more scale factors to zoom report. I did it this way:
private readonly string[] ZOOM_VALUES = { "25%", "50%", "75%", "100%", "110%", "120%", "125%", "130%", "140%", "150%", "175%", "200%", "300%", "400%", "500%" };
private readonly int DEFAULT_ZOOM = 3;
//--
public ucReportViewer()
{
InitializeComponent();
this.reportViewer1.ProcessingMode = ProcessingMode.Local;
setScaleFactor(ZOOM_VALUES[DEFAULT_ZOOM]);
Control[] tb = reportViewer1.Controls.Find("ReportToolBar", true);
ToolStrip ts;
if (tb != null && tb.Length > 0 && tb[0].Controls.Count > 0 && (ts = tb[0].Controls[0] as ToolStrip) != null)
{
//here we go if our trick works (tested at .NET Framework 2.0.50727 SP1)
ToolStripComboBox tscb = new ToolStripComboBox();
tscb.DropDownStyle = ComboBoxStyle.DropDownList;
tscb.Items.AddRange(ZOOM_VALUES);
tscb.SelectedIndex = 3; //100%
tscb.SelectedIndexChanged += new EventHandler(toolStripZoomPercent_Click);
ts.Items.Add(tscb);
}
else
{
//if there is some problems - just use context menu
ContextMenuStrip cmZoomMenu = new ContextMenuStrip();
for (int i = 0; i < ZOOM_VALUES.Length; i++)
{
ToolStripMenuItem tsmi = new ToolStripMenuItem(ZOOM_VALUES[i]);
tsmi.Checked = (i == DEFAULT_ZOOM);
//tsmi.Tag = (IntPtr)cmZoomMenu;
tsmi.Click += new EventHandler(toolStripZoomPercent_Click);
cmZoomMenu.Items.Add(tsmi);
}
reportViewer1.ContextMenuStrip = cmZoomMenu;
}
}
private bool setScaleFactor(string value)
{
try
{
int percent = Convert.ToInt32(value.TrimEnd('%'));
reportViewer1.ZoomMode = ZoomMode.Percent;
reportViewer1.ZoomPercent = percent;
return true;
}
catch
{
return false;
}
}
private void toolStripZoomPercent_Click(object sender, EventArgs e)
{
ToolStripMenuItem tsmi = sender as ToolStripMenuItem;
ToolStripComboBox tscb = sender as ToolStripComboBox;
if (tscb != null && tscb.SelectedIndex > -1)
{
setScaleFactor(tscb.Items[tscb.SelectedIndex].ToString());
}
else if (tsmi != null)
{
if (setScaleFactor(tsmi.Text))
{
foreach (ToolStripItem tsi in tsmi.Owner.Items)
{
ToolStripMenuItem item = tsi as ToolStripMenuItem;
if (item != null && item.Checked)
{
item.Checked = false;
}
}
tsmi.Checked = true;
}
else
{
tsmi.Checked = false;
}
}
}
Get the toolbar from ReportViewer control:
ToolStrip toolStrip = (ToolStrip)reportViewer.Controls.Find("toolStrip1", true)[0]
Add new items:
toolStrip.Items.Add(...)
There are a lot of properties to set which buttons would you like to see.
For example ShowBackButton, ShowExportButton, ShowFindControls, and so on. Check them in the help, all starts with "Show".
But you are right, you cannot add new buttons. You have to create your own toolbar in order to do this.
What do you mean about new version? There is already a 2008 SP1 version of it.
Another way would be to manipulate the generated HTML at runtime via javascript. It's not very elegant, but it does give you full control over the generated HTML.
For VS2013 web ReportViewer V11 (indicated as rv), the code below adds a button.
private void AddPrintBtn()
{
foreach (Control c in rv.Controls)
{
foreach (Control c1 in c.Controls)
{
foreach (Control c2 in c1.Controls)
{
foreach (Control c3 in c2.Controls)
{
if (c3.ToString() == "Microsoft.Reporting.WebForms.ToolbarControl")
{
foreach (Control c4 in c3.Controls)
{
if (c4.ToString() == "Microsoft.Reporting.WebForms.PageNavigationGroup")
{
var btn = new Button();
btn.Text = "Criteria";
btn.ID = "btnFlip";
btn.OnClientClick = "$('#pnl').toggle();";
c4.Controls.Add(btn);
return;
}
}
}
}
}
}
}
}
I had this question for al ong time I I found the answer after a long tie and the main source of kowledge I used was this webpega: I'd like to thank you all guys adding the code that allowed me to do it and a picture with the result.
Instead of using the ReportViewer Class, you need to create a new classs, in my case, I named it ReportViewerPlus and it goes like this:
using Microsoft.Reporting.WinForms;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace X
{
class ReportViewerPlus : ReportViewer
{
private Button boton { get; set; }
public ReportViewerPlus(Button but) {
this.boton = but;
testc(this.Controls[0]);
}
public ReportViewerPlus()
{
}
private void testc(Control item){
if(item is ToolStrip)
{
ToolStripItemCollection tsic = ((ToolStrip)item).Items;
tsic.Insert(0, new ToolStripControlHost(boton));
return;
}
for (int i = 0; i < item.Controls.Count; i++)
{
testc(item.Controls[i]);
}
}
}
}
You have to add the button directly in the constructor of the class and you can configure the button in your designer.
Here's a pic of the result, not perfect, but enough to go(safe link I swear, but I can't post my own pics, don't have enough reputation).
http://prntscr.com/5lfssj
If you look carefully in the code of the class, you'd see more or less how it works and you could make your changes and make it possible to establish it in other site of the toolbar.
Thank you so much for helping me in the past, I hope this helps lots of people!
Generally you are suppose to create your own toolbar if you want to modify it. Your solution for removing buttons will probably work if that is all you need to do, but if you want to add your own you should probably just bite the bullet and build a replacement.
You may modify reportviewer controls by CustomizeReportToolStrip method.
this example remove Page Setup Button, Page Layout Button in WinForm
public CustOrderReportForm() {
InitializeComponent();
CustomizeReport(this.reportViewer1);
}
private void CustomizeReport(Control reportControl, int recurCount = 0) {
Console.WriteLine("".PadLeft(recurCount + 1, '.') + reportControl.GetType() + ":" + reportControl.Name);
if (reportControl is Button) {
CustomizeReportButton((Button)reportControl, recurCount);
}
else if (reportControl is ToolStrip) {
CustomizeReportToolStrip((ToolStrip)reportControl, recurCount);
}
foreach (Control childControl in reportControl.Controls) {
CustomizeReport(childControl, recurCount + 1);
}
}
//-------------------------------------------------------------
void CustomizeReportToolStrip(ToolStrip c, int recurCount) {
List<ToolStripItem> customized = new List<ToolStripItem>();
foreach (ToolStripItem i in c.Items) {
if (CustomizeReportToolStripItem(i, recurCount + 1)) {
customized.Add(i);
}
}
foreach (var i in customized) c.Items.Remove(i);
}
//-------------------------------------------------------------
void CustomizeReportButton(Button button, int recurCount) {
}
//-------------------------------------------------------------
bool CustomizeReportToolStripItem(ToolStripItem i, int recurCount) {
Console.WriteLine("".PadLeft(recurCount + 1, '.') + i.GetType() + ":" + i.Name);
if (i.Name == "pageSetup") {
return true;
}
else if (i.Name == "printPreview") {
return true;
}
return false; ;
}