Xamarin Derived UIControl TouchUpInside event isn't working - c#

I'm trying to set an TouchUpInside event to my class that inherit from UIControl.
First, I've tried to set the event to each control separately, in the same class, and it's also not working.
Than, I've tried to set the event from the window that present this UIControl, but also isn't working.
The class drawing two controls, Button and TextField:
public class SingleItemView : UIControl
{
public UIButton RadioButton { get; set; }
public override void Draw(RectangleF rect)
{
base.Draw(rect);
this.UserInteractionEnabled = true;
RadioButton = new UIButton(rect);
RadioButton.SetImage(UIImage.FromFile("images/Unknown_Gray.png"), UIControlState.Normal);
RadioButton.HorizontalAlignment = UIControlContentHorizontalAlignment.Left;
this.AddSubview(RadioButton);
var textField = new UITextField(new RectangleF(rect.X + 25, rect.Y, rect.Width, rect.Height));
textField.Placeholder = "Place Holder is here";
this.AddSubview(textField);
}
}
The ViewController that signs the event:
public class ItmesView : UIViewController
{
public override void ViewDidLoad()
{
base.ViewDidLoad();
var item = new SingleItemView();
item.Draw(new RectangleF(10, 60, 50, 30));
item.TouchUpInside += item_TouchUpInside;
this.View.AddSubview(item);
}
}
None of the events I've tried isn't working, any suggestion?
Thanks.

Related

C# Event not firing

I'm trying to create a custom scrollable panel as TableLayoutPanels scroll function is not very customisable.
I have a custom class that inherits from Microsoft.Visualbasics.Powerpacks.RectangleShape. This class is used to create the scroll bar object. It contains a MouseDrag Event that is supposed to be triggered when the mouse is pressed down on the scroll bar and will terminate when the mouse comes back up.
This ScrollBar object is instantiated in another custom class that inherits from Forms.Panel.
In the main form method the custom panel is instantiated and the MouseDrag event is added to the ScrollBar. When I click the ScrollBar nothing happens. I even tested with the built in Click event and again nothing happens. Any help would be much appreciated.
Scroll Bar Class:
class ScrollBar : RectangleShape
{
public event MouseEventHandler MouseDrag;
private bool mouseHeld = false;
public bool MouseHeld { get => mouseHeld; set => mouseHeld = value; }
public ScrollBar()
{
InitializeObject();
}
public ScrollBar(int x, int y, int width, int height) : base(x, y, width, height)
{
InitializeObject();
}
private void InitializeObject()
{
this.MouseDown += new MouseEventHandler(mouseClickEvent);
}
public void mouseClickEvent(object sender, MouseEventArgs e)
{
MouseHeld = true;
MouseDrag(this, null);
}
}
Custom Panel Class:
class CustomPanel : Panel
{
private ScrollBar verticalScrollBar;
public ScrollBar VerticalScrollBar { get => verticalScrollBar; set => verticalScrollBar = value; }
public CustomPanel()
{
PanelSetup();
}
public CustomPanel(Size _size)
{
this.Size = _size;
PanelSetup();
}
private void PanelSetup()
{
//Panel setup
this.BackColor = Color.White;
this.Location = new Point(125, 125);
this.BorderStyle = BorderStyle.FixedSingle;
//Behind scrollbar graphic
RectangleShape behindScrollGraphic = new RectangleShape();
behindScrollGraphic.Width = 21;
behindScrollGraphic.Height = this.Height;
behindScrollGraphic.Location = new Point(this.Width - behindScrollGraphic.Width, 0);
behindScrollGraphic.FillStyle = FillStyle.Solid;
behindScrollGraphic.FillColor = SystemColors.Control;
behindScrollGraphic.BorderColor = Color.Transparent;
//adding behind scroll bar to panel
ShapeContainer shapeContainer = new ShapeContainer();
shapeContainer.Shapes.Add(behindScrollGraphic);
this.Controls.Add(shapeContainer);
}
public virtual void AddVerticalScrollBar()
{
ShapeContainer rectangleShapeContainer = new ShapeContainer();
rectangleShapeContainer.Shapes.Add(VerticalScrollBar);
this.Controls.Add(rectangleShapeContainer);
}
public virtual void CreateScrollBar(int _barWidth, int _barHeight)
{
int barWidth = _barWidth;
int barHeight = _barHeight;
VerticalScrollBar = new ScrollBar(this.Width - barWidth - 7, 5, 12, 30);
VerticalScrollBar.FillStyle = FillStyle.Solid;
VerticalScrollBar.FillColor = SystemColors.ControlDark;
VerticalScrollBar.BorderColor = Color.Transparent;
}
}
Main Form Class:
public partial class Form1 : Form
{
private CustomPanel panel;
public Form1()
{
InitializeComponent();
CheckForIllegalCrossThreadCalls = false;
//Form setup
this.Size = new Size(500, 500);
this.BackColor = Color.White;
//Panel setup
panel = new CustomPanel(new Size(250, 250));
panel.CreateScrollBar(10, panel.Height - 2);
panel.AddVerticalScrollBar();
//Scroll Bar
panel.VerticalScrollBar.MouseDrag += new MouseEventHandler(mouseHeldMethod);
//Add panel to form
this.Controls.Add(panel);
}
private void mouseHeldMethod(object sender, MouseEventArgs e)
{
Console.WriteLine("test");
while (panel.VerticalScrollBar.MouseHeld)
{
Console.WriteLine("Held");
}
}
}
Figured the problem out before anyone wastes their time, the control was being obstructed by another control even though visibly the other control was behind it, nothing wrong with the event call.

How to change a xaml button property using it's string name from c# in UWP?

Relative noob here coming from Python trying to build a UWP app in c# and XAML.
The short version: How do I refer to a button using its string 'Name' to change its color. It seems that if I have given it a name I should be able to refer to it by its name, something like:
"navBtn5".Background = myColor;
//or
navBtn5.Background = myColor;
I have looked all over, the best I found was this from here on stackOverflow:
How to control a xaml button from C# in WPF
which looks exactly like what I want. However this does not work, will not even build as I just get told:
Error CS0103 The name 'navBtn5' does not exist in the current context
This could be because I am using UWP and that is for WPF.
The long Version: My app is creating the navigation menu by data binding to a List that is put together in a separate class. I am creating a type of MenuButton in my class then returning a list of them. This is a stripped down version of my class:
class MenuButton{
public string buttonName { get; set; }
public string buttonContentText { get; set; }
public int buttonWidth { get; set; }
public int buttonHeight { get; set; }
public List<byte> buttonColor { get; set; }
}
class menuButtonManager{
public static List<MenuButton> getButtons(){
var menuButtons = new List<MenuButton>();
menuButtons.Add(new MenuButton{
buttonName = "navBtn1",
buttonWidth = 50,
buttonHeight = 50,
buttonContentText = "\uE173",
buttonColor = new List<byte> { 255, 82, 190, 128 },
});
menuButtons.Add(new MenuButton{
buttonName = "navBtn2",
//and so on
});
menuButtons.Add(new MenuButton{
//and so on
});
}
return menuButtons;
}
At Run Time, when the user clicks a button I want to loop through all the buttons in the List and change their color to grey if it was not that one that was clicked, green if it was the clicked button. something like this:
private void navClick(object sender, RoutedEventArgs e){
//who called me
string senderName = ((Button)sender).Name;
foreach(MenuButton m in menuButtons){
if(m.buttonName == senderName){
Button senderButton = (Button)sender;
senderButton.Background = myFunkyColor;
// I can already do this as I already have
// the sender cast to a button
}
else{
// change button to grey
// This is where I am stuck
// I know m.buttonName as a string
// how do I create a usable button object from it?
}
}
}
As you can see I have no trouble changing the properties of the button that was the sender as I have cast it to a type of Button which I can use. The problem for me is when I am acting on a button that is not the sender and all I have is it's string name.
You do not have to create a new class if you are using default properties(Unless it is your requirement).
Make your List of Buttons Global
List< Button> menuButtons = new List< Button>();
public static List<Button> getButtons()
{
for ( int i=0; i<5; i++)
{
Button _button = new Button
{
Name = "navBtn" + i.ToString(),
Width = 50,
Height = 50,
Content = "\uE173",
Background = new SolidColorBrush(Colors.Gray)
};
_button.Click += _button_Click;
menuButtons.Add(_button);
}
return menuButtons;
}
The above will return 5 new buttons( something like your requirement ). Look at
_button.Click += _button_Click;
An event for click will be explicitly created for each button in the list.
private static void _button_Click(object sender, RoutedEventArgs e)
{
Button Clicked = (Button)sender;
foreach(Button btn in menuButtons)
{
if (Clicked.Name == btn.Name)
{
btn.Background = myFunkyColour;
}
else
{
btn.Background = //Your Disabled Colour.
}
}
}
Click event will return you the button that was clicked.
Hope this helps.

Mouse events for Picture box that is Created in a C# class

I am Creating a Chess.I added a Picture box on design form as Chessboard..then for each piece (for example horse or elephant and...) Added a Class.cs and created picture box for each piece in those classes.like this:
public class Mohre
{
public Mohre()
{
}
public void draw(Form form,PictureBox pic )
{
pic.Size = new System.Drawing.Size(50, 50);
pic.Image = Chess1.Properties.Resources.sarbaz;
pic.SizeMode = PictureBoxSizeMode.StretchImage;
pic.Visible = true;
form.Controls.Add(pic);
pic.BringToFront();
}
}
&
public class Soldier:Mohre
{
public PictureBox picsoldier = new PictureBox();
public Soldier()
{
picsoldier.Left = 436;
picsoldier.Top = 670;
}
public void movement()
{
picsoldier.Top -= 67;
}
}
(not add picture box on design form Directly.) now I want to when user click on the pieces that created in classesÙˆ movement function will be called.
what should I Do?
You mean this ?
lblname.Click += delegate { nameOfUrFunction (lblname); };
private void nameOfUrFunction (Label lbl)
{
}

WPF InkCanvas inherit class

I want to create an custom InkCanvas Adorner and found the logic behind:
You can re-use the existing lasso functionality of the InkCanvasEditingMode.Select mode. Then, in the SelectionChanged event, you can get a reference to the selected strokes (and/or elements). Now clear the selection (to get rid of the standard adorner) and then bring up your custom adorner.
How can i inherit the InkCanvas class with the editing mode in my own class and get access to the Events?
class myInkCanvasClass : InkCanvas ?
{
base class constructor call ?
...
}
[DebuggerDisplay("[{Scene}]Strokes:{Strokes.Count}, Children:{Children.Count}")]
public class InkCanvas_Sandeep : InkCanvas
{
public int PagId = -1;
public InkCanvas_Sandeep()
{
DefaultDrawingAttributes.Color = Colors.Red;
DefaultDrawingAttributes.FitToCurve = true;
DefaultDrawingAttributes.Height = 2;
DefaultDrawingAttributes.Width = 2;
DefaultDrawingAttributes.IgnorePressure = false;
DefaultDrawingAttributes.IsHighlighter = false;
DefaultDrawingAttributes.StylusTip = System.Windows.Ink.StylusTip.Ellipse;
DefaultDrawingAttributes.StylusTipTransform = Matrix.Identity;
HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
VerticalAlignment = System.Windows.VerticalAlignment.Stretch;
SnapsToDevicePixels = true;
}
}
public void createMultipleInstances()
{
InkCanvas_Sandeep canvas new InkCanvas_Sandeep();
canvas.PagId = ++PageDetails.PageId;
}
You shouldn't have to inherit from InkCanvas, SelectionChanged is a public event on InkCanvas so you can just add a handler to it. Also the EditingMode is a public property that you can set on an instance of InkCanvas as well. So to add the handler to SelectionChanged and toggle the EditingMode between Ink and Select you can just use the public API of an InkCanvas instance.
Basic example:
inkCanvas.SelectionChanged += InkCanvas_SelectionChanged;
inkCanvas.EditingMode = InkCanvasEditingMode.Select;
I managed to inherit the InkCanvas Class to my CustomInkCanvas Class and get the EventListener of SelectionChanged:
public class CustomInkCanvas : InkCanvas
{
//variables
//constructor
public CustomInkCanvas()
{
//...
}
override protected void OnSelectionChanged(EventArgs e)
{
MessageBox.Show("Selection Changed");
}
}
So if i change a Selection i get noticed.

Creating Smart Tag for Form (not other control) using c#

As the Form of System.Windows.Forms inherits from Control, I was wondering if there is a way to create a Custom Form and its Designer with some options (shortcuts) to create a title or somthings like that.
I tried this, but nothings happend, the Form I calles ManagedForm
[Designer(typeof(ManagedFormDesigner))]
public class ManagedForm : Form{
//code here
}
[PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
public class ManagedFormDesigner : ControlDesigner {
private DesignerActionListCollection actionLists;
public override DesignerActionListCollection ActionLists {
get {
if (actionLists == null) {
actionLists = new DesignerActionListCollection();
actionLists.Add(new ManagedFormDesignerActionList(this.Component));
}
return actionLists;
}
}
}
public class ManagedFormDesignerActionList : DesignerActionList {
private ManagedForm managedForm = null;
private DesignerActionUIService designerActionUISvc = null;
public ManagedFormDesignerActionList(IComponent component) : base(component) {
this.managedForm = component as ManagedForm;
this.designerActionUISvc =
GetService(typeof(DesignerActionUIService))
as DesignerActionUIService;
}
public override DesignerActionItemCollection GetSortedActionItems() {
DesignerActionItemCollection items = new DesignerActionItemCollection();
items.Add(new DesignerActionMethodItem(this, "CreateTitle", "Create Title", "Appearence", true));
return items;
}
public void CreateTitle() {
Panel pTitulo = new Panel();
pTitulo.Size= new Size(100,25);
pTitulo.Dock = DockStyle.Top;
(this.Component as ManagedForm).Controls.Add(pTitulo);
}
}
Action list are show when you click on the little arrow on the control inside a form (or on a component on the bottom of the designer if the object is a component).
Other things you can do is to manage verbs.
Verbs Handling is implemented on the ControlDesigner class (ManagedFormDesigner in your case).
You can see verbs clicking right mouse button or on the bottom of the properties (i.e. TabControl ha 2 verbs, add tab and remove tab).
You can implement verbs adding to ControlDesigner (or ComponentDesigner) class something like this
private DesignerVerbCollection _verbs;
public override DesignerVerbCollection Verbs
{
get
{
if (_verbs == null)
{
_verbs = new DesignerVerbCollection();
_verbs.Add(new DesignerVerb("Create Title", new EventHandler(MyCreateTitleHandler)));
}
return _verbs;
}
}
private void MyCreateTitleHandler(object sender, EventArgs e)
{
// Do here something but take care to show things via IUIService service
IUIService uiService = GetService(typeof(IUIService)) as IUIService;
}

Categories

Resources