I want to create many button by Foreach,and these Buttons print Uri's Properties. but I don't know how to do it. can you tell me how to do it ?
this is my code:
private void CreateButtons()
{
Uri uri = new Uri("/Pages/PageTest.xaml?Name=Stephen&Age=17",UriKind.Relative);
foreach(var pi in typeof(Uri).GetProperties())
{
//create button
Button btn = new Button();
btn.Content = pi.Name;
btn.Margin = new Thickness(0,0,0,12);
//i think this is bug, but i don't know,how to do
btn.Click += (se,ev)=>
{
MessageBox.Show(pi.GetValue(btn,null).ToString());
}
stackPanel.Children.Add(btn);
}
}
You are using wrong target for
pi.GetValue(btn,null)
You are quering URI properties but your target is button object.
You need something like:
MessageBox.Show(pi.GetValue(uri, null).ToString());
I'm guessing you are getting an exception in the event handler.
Try enabling breaking when exceptions are thrown (Debug|Exceptions -> check "Thrown" next to Common Language Runtime Exceptions").
Then run with debugger attached and see what happens when you click a button. I suspect a NullPointerException
Related
In developing a mod for Cities: Skylines, I have run across a problem.
Most of my code, as far as I can tell, works fine - but so far, I haven't got to test it. This is because it should all get called in sequence when a button I have added to the UI gets clicked. The click event on this button is not calling the handler I've assigned to it.
This is where I create the button:
public class LoadingExtension : LoadingExtensionBase
{
public override void OnLevelLoaded(LoadMode mode)
{
Debug.LogDebugMessage("Adding 'Generate City Report' button to UI");
// Get the UIView object. This seems to be the top-level object for most
// of the UI.
var uiView = UIView.GetAView();
// Add a new button to the view.
var button = (UIButton)uiView.AddUIComponent(typeof(UIButton));
// Set the text to show on the button.
button.text = "Generate City Report";
// Set the button dimensions.
button.width = 250;
button.height = 30;
// Style the button to look like a menu button.
button.normalBgSprite = "ButtonMenu";
button.disabledBgSprite = "ButtonMenuDisabled";
button.hoveredBgSprite = "ButtonMenuHovered";
button.focusedBgSprite = "ButtonMenuFocused";
button.pressedBgSprite = "ButtonMenuPressed";
button.textColor = new Color32(255, 255, 255, 255);
button.disabledTextColor = new Color32(7, 7, 7, 255);
button.hoveredTextColor = new Color32(7, 132, 255, 255);
button.focusedTextColor = new Color32(255, 255, 255, 255);
button.pressedTextColor = new Color32(30, 30, 44, 255);
// Enable button sounds.
button.playAudioEvents = true;
// Place the button.
button.transformPosition = new Vector3(-1.0f, 0.97f);
// Respond to button click.
// NOT GETTING CALLED
button.eventClick += ButtonClick;
}
public void ButtonClick(UIComponent component, UIMouseEventParameter eventParam)
{
Debug.LogWarningMessage("HIGH LOGIC: Beginning report generation.");
string now = DateTime.Now.ToFileTime().ToString();
string filepath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
string filename = filepath + "\\CityReport-" + now + ".xlsx";
Output fileCreator = new Output(filename);
fileCreator.GenerateReport();
}
}
According to the documentation I've been following, using
button.eventClick += ButtonClick;
should add ButtonClick as the click handler for the button. However, clicking on the button does nothing. The debug message at the start of the handler (the "HIGH LOGIC" message) doesn't get displayed (note: the earlier debug message about adding the button to the UI does). No error messages are displayed either in the game's debug panel or in VS.
I have also tried using new MouseEventHandler(ButtonClick), since the VS inline documentation tells me that the type of eventClick is MouseEventHandler. This doesn't show any errors in VS or the game, but doesn't work either.
(Note: there is official documentation, but it's next to useless.)
Does anyone here have experience with the C:S API? Why is this event not getting called?
You might try taking a small step back to check if a different UI element works; for example, by following the example for adding a UILabel. Registering a click event handler to this one possibly might work, since there's an actual example to follow; although, the documentation says to place this code inside the Start method. I'm not sure, but maybe the UIButton in your code should be placed in a Start method as well.
As an aside, I stumbled upon this link for debugging. Skylines seems to have its own messaging system for debugging.
Something that I did notice in your code is that the first Debug statement uses a different method than the second Debug statement:
Debug.LogDebugMessage("Adding 'Generate City Report' button to UI");
Debug.LogWarningMessage("HIGH LOGIC: Beginning report generation.");
It might not make any difference, but I would test out that Debug.LogWarningMessage call by moving it where the Debug.LogDebugMessage is to see if it actually works.
According to the extremely terse documentation there's a log file called output_log.txt, perhaps there might be some info contained within this file.
Have you tried:
//button.eventClick += ButtonClick;
button.eventClick += (c,e) => {
Debug.LogWarningMessage("HIGH LOGIC: Beginning report generation.");
string now = DateTime.Now.ToFileTime().ToString();
string filepath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
string filename = filepath + "\\CityReport-" + now + ".xlsx";
Output fileCreator = new Output(filename);
fileCreator.GenerateReport();
};
Also have you tried doing this?:
//var button = (UIButton)uiView.AddUIComponent(typeof(UIButton));
var button = uiView.AddUIComponent(typeof(UIButton)) as UIButton
(Sorry, i can't coment yet)
It looks like your click handler, as such, is OK. Change your ButtonClick method to:
public void ButtonClick(UIComponent component, UIMouseEventParameter eventParam)
{
Debug.LogWarningMessage("HIGH LOGIC: Beginning report generation.");
}
and then check the debug output. If you have a bug after that line, then the debug message may not be visible.
I want to use information on which control was clicked for setting up the page. I use this to set up a sortable table in code. I found through this forum that I can use Request.Form.Get("__EVENTTARGET") for that. However, as soon as I do something with that parameter, the callback function is no longer called. Is this expected behavior or am I making a mistake?
Here some snippets of my code. The code in Page_Load() is:
string sortRequest = Request.Form.Get("__EVENTTARGET");
bool isCurrentField = false;
if (sortRequest != null) isCurrentField = sortRequest.Contains(header.Field);
if (!isCurrentField)
{
// Add a hyperlink for sorting to the cell
LinkButton newLink = new LinkButton();
newLink.Text = header.Title;
newLink.Font.Bold = true;
newLink.ID = "link" + header.Field;
newLink.CommandName = "Sort";
newLink.CommandArgument = header.Field;
newLink.Command += new CommandEventHandler(LinkButton_Command);
hdrCell.Controls.Add(newLink);
}
else
{
hdrCell.Text = header.Title;
hdrCell.Font.Bold = true;
}
My callback:
public void LinkButton_Command(Object sender, CommandEventArgs e)
{
_sortOrder = e.CommandArgument.ToString();
}
I have also tried it with copying the sortRequest into a temporary variable, but that doesn't make a difference. As soon as I comment out the line if (sortRequest != null) isCurrentField = sortRequest.Contains(header.Field);, the callback is called again.
There is a fault in your logic. You have a dynamically created control LinkButton with LinkButton_Command event handler connected to it. For the server-side event to fire on postback, the control must be present in the page control tree. This means the dynamic LinkButton must be created, configured and added to hdrCell.Controls always, regardless of sortRequest value. Only then will it be able to pick up the fact that it was clicked from the Request and fire its Command event.
I've got a problem with adding some controls into a Panel(which gets "PopUpped" by a ModalPopupExtender) and add a CheckedChanged-EventHandler.
First of all, when user clicks on a button, this happens inside the CreatePanelChoose() function:
foreach (ListItem item in lbSupplier.Items)
{
string cbid = "cb" + i;
CheckBox cb = new CheckBox();
cb.ID = cbid;
cb.Text = item.Text;
cb.AutoPostBack = true;
AjaxControlToolkit.MutuallyExclusiveCheckBoxExtender mecbe = new AjaxControlToolkit.MutuallyExclusiveCheckBoxExtender();
mecbe.ID = "mecbe" + cbid;
mecbe.TargetControlID = cbid;
mecbe.Key = "SupplierKEY";
mecbe.BehaviorID = mecbe.ID + i;
//Also adding a Label
phModalPopupExtender.Controls.Add(new LiteralControl("</br>")); //phModalPopupExtender is a PlaceHolder
phModalPopupExtender.Controls.Add(cb);
phModalPopupExtender.Controls.Add(mecbe);
phModalPopupExtender.Controls.Add(lbl);
AsyncPostBackTrigger trigger = new AsyncPostBackTrigger();
trigger.ControlID = cbid;
trigger.EventName = "CheckedChanged";
UpdatePanelMatrix.Triggers.Add(trigger);
i++;
ButtonOK.Enabled = false;
}
lblText.Text = "Select one Supplier";
ModalPopupExtender1.Show();
Then i add the EventHandler in the Page_LoadComplete:
As you can see it also gets asigned to the control (I think).
The ModalPopup shows up correctly, but if I click one of the CheckBox, then it just closes it without going into cb_CheckedChanged, but it makes a Async postback ...
If I check Request.Form["__ASYNCPOST"] its true and Request.Form["__EVENTTARGET"] is also correct. (It gives me the unique id!)
Request.Form["__EVENTARGUMENT"] is empty.
I think I also need to say that I use a masterpage.
The problem shouldn't be the lifecycle of the page, because msdn says:
LoadComplete
Raised at the end of the event-handling stage.
Use this event for tasks that require that all other controls on the page be loaded.
Its the onliest place it makes me think it would be right.
Btw: yes i looked trough the topics here allready, but nothing helped me ... (google fo sure also)
Edit 1:
if (IsPostBack)
{
if (recreating == true)
{
CreatePanelChoose();
}
}
In CreatePanelChoose i do the foreach now everytime when its a postback! But it still doesnt fire cb_ChangedChecked ...
Edit 2:
MSDN-Page-Lifecycle also says:
PreInit
Raised after the start stage is complete and before the initialization
stage begins.
Use this event for the following:
Create or re-create dynamic controls.
So i tried to recreate the Panel there. But i dont have the ListItems there to get the values ... ?!
Okay, gave up ...
If someone would still have an answer, it would be great!
Right now I dont use the OnCheckedChanged-Event of the CheckBoxes anymore.
I just let them select a CheckBox and on the OnClick of the ButtonOk I loop through the CheckBoxes and check which one is selected.
I'm trying to create a DevEx drop down button. Unfortunately, I'm running into two problems I can't figure out:
1) I can't get the popup menu to skin correctly, i.e. it doesn't skin as "Office 2010 Blue". The code I'm using is shown below:
private void InitializeSendToPricingSheetButton()
{
var barManager = new BarManager();
if (barManager.Controller == null) barManager.Controller = new BarAndDockingController();
barManager.Controller.PaintStyleName = "Skin";
barManager.Controller.LookAndFeel.UseDefaultLookAndFeel = false;
barManager.Controller.LookAndFeel.SkinName = "Office 2010 Blue";
barManager.ItemClick += HandleSendToPricingSheetClick;
barManager.Items.AddRange(new[] { new BarButtonItem(barManager, "Foo"), new BarButtonItem(barManager, "Bar"), new BarButtonItem(barManager, "Baz") });
var popupMenu = new PopupMenu { Manager = barManager };
foreach (var barItem in barManager.Items) popupMenu.ItemLinks.Add((BarItem)barItem);
popupMenu.ItemLinks[1].BeginGroup = true;
dropDownButtonSendToPricingSheet.DropDownControl = popupMenu;
}
2) This button is on a form. If the form loses focus (e.g. I click on Firefox), the pop-up menu still remains on-top. It won't go away until clicked.
Any suggestions would be much appreciated. Thanks for helping me deal with DevEx insanity.
I have solution to your second question.
You should add drop down button event handler as below:
dropDownButton1.LostFocus += new EventHandler(HidePopUp);
Handler method should be as below:
private void HidePopUp(object sender,object e)
{
dropDownButton1.HideDropDown();
}
For your second question, you should assign value to the bar manager property as:
BarManager manager = new BarManager();
manager.Form = this; // refers to current form
Find below link for reference
https://www.devexpress.com/Support/Center/Question/Details/Q274641
It is probably simpler to use DefaultLookAndFeel
Add this comp to your form and set the theme you'd like to use.
There is no need to set the theme for individual components.
defaultLookAndFeel1.LookAndFeel.SetSkinStyle("Office 2010 Blue");
Currently, what I'm doing is this:
Using the built-in .NET PrintPreviewDialog
Attaching my own Click handler to the Print button, which allows for the user to select the printer before finally printing.
This all WORKS, HOWEVER, the OnprintToolStripButtonClick event is still sending the document to the default printer BEFORE the user gets to choose the actual printer and click Print (which works, but they're getting an extra copy on the default printer first from the old Handler).
Can I remove this built-in Click handler? I've tried the other methods mentioned on here in regards to using an EventHandlerList to remove the handlers, but it doesn't work for the built-in printing event. Here is a copy of my current code in case it helps clarify:
// ... Irrelevant code before this
private PrintPreviewDialog ppdlg;
ToolStrip ts = new ToolStrip();
ts.Name = "wrongToolStrip";
foreach (Control ctl in ppdlg.Controls)
{
if (ctl.Name.Equals("toolStrip1"))
{
ts = ctl as ToolStrip;
break;
}
}
ToolStripButton printButton = new ToolStripButton();
foreach (ToolStripItem tsi in ts.Items)
{
if (tsi.Name.Equals("printToolStripButton"))
{
printButton = tsi as ToolStripButton;
}
}
printButton.Click += new EventHandler(this.SelectPrinterAfterPreview);
// ... Irrelevant code afterwards omitted
// Here is the Handler for choosing a Printer that gets called after the
// PrintPreviewDialog's "Print" button is clicked.
private void SelectPrinterAfterPreview(object sender, EventArgs e)
{
frmMainPage frmMain = (frmMainPage)this.MdiParent;
if (frmMain.printDialog1.ShowDialog() == DialogResult.OK)
{
pd.PrinterSettings.PrinterName = frmMain.printDialog1.PrinterSettings.PrinterName;
pd.PrinterSettings.Copies = frmMain.printDialog1.PrinterSettings.Copies;
pd.Print();
}
}
Since you have access to the buttons in the toolstrip, remove the old print button and add your own. Assign the image from the default print button and you are all set. The code woudl look something like this:
ts.Items.Remove(printButton);
ToolStripButton b = new ToolStripButton();
b.ImageIndex = printButton.ImageIndex;
b.Visible = true;
ts.Items.Insert(0, b);
b.Click += new EventHandler(this.SelectPrinterAfterPreview);
I think replace buttons or use the Control Names from PrintPreviewDialog isĀ“nt a good option.
From Net1 to Net2 changes the name for the ToolBar. Next version can also change it or the name for other controls.
The PrintPreviewDialog is a very simple Form to encapsulate PrintPreviewControl.
You can build a new Form and put own buttons and implement your funcionality.
You can find some Dialogs for PrintPreview at Code-Project (CoolPrintPreviewDialog) An Enhaced PrintPreviewDialog.
On my PrvDialog, when user press the Print Button I show a PageSelDialog to allow the user select Range to Print (Current page, Some Pages, All-Pages, Cancel).
Other solution is override OnBeginPrint / suscribe event BeginPrint from PrintDocument.
Here you can show the PageSelDialog, cancel the Print and alter the DefaultPageSettings PrintRange, FromPage, ToPage.
For this Option you need know when is PrintToPrinter, Preview or Print From PrintButon.
PrintController.IsPreview, resolve for Preview Option.