I have trouble with my custom Widget in Xamarin-Studio, where I use Mono, C# and Gtk#.
It should show 2 images and 2 label, should work like a Button and should be hide-able.
This is my code:
using System;
using GLib;
using Gtk;
using System.Runtime.InteropServices;
namespace myProgram_V1
{
[System.ComponentModel.ToolboxItem (true)]
public partial class myWidget : Gtk.Bin
{
public myWidget ()
{
this.Build ();
HeightRequest = 128;
}
public void setHeight (int height)
{
HeightRequest = height;
}
public void setLabel1 (String text)
{
label1.Text = text;
}
public void setLabel2 (String text)
{
label2.Text = text;
}
public void setImage1 (String image)
{
image1.Pixbuf = new Gdk.Pixbuf (image);
}
public void setImage2 (String image)
{
image2.Pixbuf = new Gdk.Pixbuf (image);
}
[Signal ("clicked")]
public event EventHandler Clicked {
add {
Signal signal = Signal.Lookup (this, "clicked");
signal.AddDelegate (value);
}
remove {
Signal signal = Signal.Lookup (this, "clicked");
signal.RemoveDelegate (value);
}
}
}
}
If I use this widget in the GUI-Designer of other widgets/windows like this, it is recognized by the Designer and I can set a Clickevent in the properties, but if I run the program, I get
(myProgram_V1:914): GLib-GObject-WARNING **: gsignal.c:2375: signal `clicked' is invalid for instance `0x7a9c9980' of type `__gtksharp_2_myProgram+5fV1_myWidget'
and it is not clickable.
But if I let it inherit from Gtk.Button instead of Gtk.Bin the widget is not usable with the Designer, but it can be used during runtime, if I set the click event beforehand and sometimes, during building or compiling, all global::myProgram_V1.myWidget entries in the auto generated file by the GUI-Designer are replaced with void and nothing will work anymore.
Also, .Hide() won't work with this widget and the only option to 'hide' this widget is to use .Destroy().
Thank you in advance for your help.
Related
I have a textbox (TextBoxMoeda) made by me, but, even when the textbox property readonly is set true. nothing happens. Anyone knows how to implement the code to resolve this problem?. Please help me?
public class TextBoxMoeda : TextBox
{
private double dp;
private string fmt = string.Empty;
private int _CasasDecimais = 0;
[Category("TextBoxMoeda")]
public virtual bool SomenteLeitura
{
get => base.ReadOnly;
set
{
base.ReadOnly = value;
Invalidate();
}
}
//Code Continues .......
}
WPF
You want the IsReadOnly property, not the ReadOnly property.
For example:
Create a new WPF App (.NET Framework) project called DeleteMe
In MainWindow.xaml, delete the Grid
In MainWindow.xaml.cs, use this code:
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
namespace DeleteMe
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var tm = new TextBoxMoeda();
this.AddChild(tm);
tm.SomenteLeitura = true;
}
public class TextBoxMoeda : TextBox
{
[Category("TextBoxMoeda")]
public virtual bool SomenteLeitura
{
get => base.IsReadOnly;
set
{
base.IsReadOnly = value;
}
}
}
}
}
The textbox will be readonly (i.e. I can't type anything into the textbox).
WinForms
The code already appears to work in WinForms. These steps will produce a working project:
Create a new Windows Forms App project called DeleteMeAgain
Overwrite all of the Form1.cs code with this:
using System.ComponentModel;
using System.Windows.Forms;
namespace DeleteMeAgain
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
var tm = new TextBoxMoeda();
this.Controls.Add(tm);
tm.SomenteLeitura = true;
}
public class TextBoxMoeda : TextBox
{
[Category("TextBoxMoeda")]
public virtual bool SomenteLeitura
{
get => base.ReadOnly;
set
{
base.ReadOnly = value;
Invalidate();
}
}
}
}
}
The textbox will be readonly (i.e. I can't type anything into the textbox).
Windows Form: User Control
Do this:
Create a new Windows Forms App called DeleteMe3
Set Target Framework to .NET Core 3.1 (Long-term support)
In your project, create a new UserControl with the filename TextBoxStack.cs
Overwrite all of the code for that user control with this:
using System.ComponentModel;
using System.Windows.Forms;
namespace DeleteMe3
{
public partial class TextBoxStack : TextBox
{
[Category("TextBoxStack")]
public virtual bool SomenteLeitura
{
get => base.ReadOnly;
set
{
base.ReadOnly = value;
Invalidate();
}
}
}
}
An error will appear. Go to the source of the error and delete that line.
Build the solution
Add your new user control to Form1
Select the new user control on the form
Change the SomenteLeitura property to True
Run the project. The textbox should be grey and readonly.
This code use with code of win form.So I want to use it with DevExpress and the problem is I don't know which tool in DevExpress that I can use instead of this code.I have a class below: Thanks
using System.Drawing;
using System;
namespace Extender
{
public class MenuItem : System.Windows.Forms.ToolStripMenuItem
{
private string _Command;
public string Command
{
get
{
return _Command;
}
set
{
_Command = value;
}
}
private object _Argument;
public object Argument
{
get
{
return _Argument;
}
set
{
_Argument = value;
}
}
private Int16 _ModuleID;
public Int16 ModuleID
{
get
{
return _ModuleID;
}
set
{
_ModuleID = value;
}
}
public MenuItem()
{
}
public MenuItem(string text)
{
this.Text = text;
}
public MenuItem(string text, EventHandler onclick) :
this(text)
{
this.Click += onclick;
}
}
}
And the code below is the method that I use to create menu from database using entity framework with winform
private void LoadMenus(ToolStripItemCollection Menu,string ParentName)
{
using (var ctx = new CambbusEntities())
{
foreach (var obj in ctx.view_ObjectDetails.Where(a => a.ObjectType == "MENU" && a.ParentName==ParentName &&a.LanguageID == Cambbus.Properties.Settings.Default.LanguageID ).OrderBy(a=>a.SortOrder))
{
string mText = obj.ObjectText;
string nName = obj.ObjectName;
if (mText == "-")
continue;
Extender.MenuItem m = new Extender.MenuItem(mText);
m.Alignment = ToolStripItemAlignment.Left;
//m.Text = obj.ObjectText;
//m.Name = obj.ParentName;
m.ModuleID = (Int16)obj.ModuleID;
m.Command = obj.Command;
m.Argument = obj.Argument;
m.Image = App.GetImageByEntity((obj.ImageTag)+"");
if (m.Command!=""){
m.Click += DynamicMenuClick;
}
bool Is4Perm = obj.ModuleID > 0;
if(Is4Perm){
m.Enabled = CurrentUser.CanViewModule((Int16)obj.ModuleID);
}
Int16 shortcutNum = ((Int16)(obj.ShortcutNum));
if (shortcutNum != 0)
{
m.ShortcutKeys = ((System.Windows.Forms.Keys)(Keys.Control)) | ((System.Windows.Forms.Keys)(shortcutNum));
}
Menu.Add(m);
LoadMenus(m.DropDownItems,nName);
}
}
}
The problem is I don't know the properties of DevExpress that can use instead winform. So can I use DevExpress instead of winform?
this is my image of winform
and I want to change to DevExpress same as in picture DevExpress Menu by using my class and method.thanks
DevExpress bars have several types of menu item. Their list is available at The List of Bar Items and Links. Since you need to handle a click on an item, I think you need BarButtonItem. You can set its caption by using the BarButtonItem.Caption property. For a click, handle the BarItem.ItemClick event.
Edited
With DevExpress, you can replace the orange tool bar with a Bar. For this, simply place BarManager on your form. It creates some default bars. Program, Sales, Help, etc. commands can be replaced with BarButtonItems as I described above. Listings and its sub items can be done by using BarSubItem. I see that you have the Windows item. If your application is MDI, I suggest you use BarMdiChildrenListItem. It will automatically generate items for all MDI child forms.
If you need to generate items in code, refer to the BarManager Class help topic that provides some code for this.
I created a custom form (FormBorderStyle = FormBorderStyle.None).
I draw my own caption bar at the top with my own custom caption buttons (Close, Maximize ...).
Now my only problem is adding normal user controls to that form. If I give these controls a location, the locations are relative to the form's top (including the caption bar).
I override the default ClientSize & ClientRectangle using the 'new' keyword, which allows me to adjust it (thus removing the caption bar out of it).
This does not seem to work and I haven't been able to figure out how to do this properly without 'hacking' the ControlAdded event (which is still buggy).
protected override void OnControlAdded(ControlEventArgs e)
{
base.OnControlAdded(e);
if (e.Control.GetType() != typeof(VlufiCaptionButton /* Caption buttons: close, minimize & maximize, should not be included */))
{
e.Control.Location = new Point(e.Control.Location.X + ClientRectangle.X, e.Control.Location.Y + ClientRectangle.Y);
e.Control.LocationChanged += Control_LocationChanged;
}
}
private void Control_LocationChanged(object sender, EventArgs e)
{
if (!childControlLocationChangedHandled)
{
System.Diagnostics.Debug.WriteLine("changing");
Control cControl = (Control)sender;
childControlLocationChangedHandled = true;
cControl.Location = new Point(cControl.Location.X + ClientRectangle.X, cControl.Location.Y + ClientRectangle.Y);
}
else
childControlLocationChangedHandled = false;
}
This is the code I currently use, but it's superbuggy & I'm still having other problems with my customly drawn border.
Does anybody know how I should correctly handle this ?
I found a decent solution: I added a ContainerControl to the form & I position & size this according to the form, then whenever adding a control to the form, it should be added to the ContainerControl. Still not a proper solution, but it's the best one so far.
I'd still appreciate if someone came up with another solution.
read comments for detail:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace WindowsApplication1
{
public partial class Form1 : Form
{
int dy = 0;
public Form1()
{
InitializeComponent();
//i add a panel to top form
//( for simulating your caption bar) and get its height
dy = panel1.Height; //for yours its your caption bar height
}
private void button1_Click(object sender, EventArgs e)
{
//adding button control between form top and panel end area
//( simulate in your caption bar )
Button btn = new Button();
btn.Location = new Point(panel1.Location.X+40,panel1.Location.Y+10);
btn.Text = "Salam";
this.Controls.Add(btn);
}
//in control added event i add dy ( height of ignored area) to control Location
private void Form1_ControlAdded(object sender, ControlEventArgs e)
{
e.Control.Location = new Point(e.Control.Location.X, e.Control.Location.Y + dy);
}
private void button2_Click(object sender, EventArgs e)
{
this.Close();
}
}
}
Ok after all, I have finally found a working and pretty nice solution.
What I did is override the Controls property of my custom Form, using my own custom ControlCollection.
So this is what I got in my custom form:
public Control.ControlCollection RealControls
{
get
{
return base.Controls;
}
}
public new CustomControlCollection Controls { get; private set; }
public ContainerControl ControlContainer { get; set; }
And this is the custom ControlCollection:
public class CustomControlCollection
{
public VlufiForm Owner { get; private set; }
public CustomControlCollection (VlufiForm pOwner)
{
Owner = pOwner;
}
public void Add(Control c)
{
Add(c, false);
}
public int Count
{
get
{
return Owner.ControlContainer.Controls.Count;
}
}
public Control this[int index]
{
get
{
return Owner.ControlContainer.Controls[index];
}
}
public void Add(Control c, bool isUsable)
{
if (isUsable)
Owner.RealControls.Add(c);
else
Owner.ControlContainer.Controls.Add(c);
}
public void SetChildIndex(Control c, int nIndex)
{
Owner.ControlContainer.Controls.SetChildIndex(c, nIndex);
}
}
This is just an example custom control collection, you could add more methods in it (thus kind of inheriting ControlCollection more).
I haven't found any bugs in this system yet, it works perfectly at the moment.
EDIT: found a bug, if you dock a control in Visual Studio's Designer Mode, it will dock in the whole form, this doesn't appear when running though.
i got some little problems. I want to write some unittest fora c#/wpf/interactivty project with visual studio 2010. and dont forget im a beginner, so sorry for that ;)
the unittest should simulate a (virtual) Key Down Event on a textbox and the result should raise an action.(Action result: Console output - just to check as first step)
i still fixed 2 problems -> the dispatcher problem & the presentationSource bug.
The unittest still simulates the keyevent and the keyevent reached the textbox but the question is, why the action not raised through the keydown event on the textbox?
It's a threading problem? what's my missunderstand?
here is the code
The Unittest
at the end of the unittest u could check the textbox - the keyboard works
[TestMethod]
public void simpleTest()
{
var mockWindow = new MockWindow();
//simple test to check if the virtualKeyboard works
string CheckText = "Checktext";
mockWindow.SendToUIThread(mockWindow.textbox, CheckText);
mockWindow.SendToUIThread(mockWindow.textbox, "k");
//needed to start the dispatcher
DispatcherUtil.DoEvents();
}
the Dispatcher fix
public static class DispatcherUtil
{
[SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
public static void DoEvents()
{
DispatcherFrame frame = new DispatcherFrame();
Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, new DispatcherOperationCallback(ExitFrame), frame);
Dispatcher.PushFrame(frame);
}
private static object ExitFrame(object frame)
{
((DispatcherFrame)frame).Continue = false;
return null;
}
}
My Testaction
class TestAction : TriggerAction<UIElement>
{
protected override void Invoke(object parameter)
{
Console.WriteLine("testAction invoke");
}
}
The MockWindow
public class MockWindow : Window
{
public TextBox textbox { get; private set; }
public MockWindow()
{
//add a grid&textbox
Grid grid = new Grid();
textbox = new TextBox();
this.Content = grid;
grid.Children.Add(textbox);
//create the testaction/triggerEvent & add them
TestAction testAction = new TestAction();
System.Windows.Interactivity.EventTrigger TestTrigger = new System.Windows.Interactivity.EventTrigger();
TestTrigger.EventName = "KeyDown";
TestTrigger.Actions.Add(testAction);
TestTrigger.Attach(this.textbox);
}
//enter a keyboard press on an UIElement
public void SendToUIThread(UIElement element, string text)
{
element.Dispatcher.BeginInvoke(new Action(() =>
{
SendKeys.Send(element, text);
}), DispatcherPriority.Input);
}
}
the MockKeyboard added from codeplex sendkeys + a presentationCore fix for unittest(added at class SendKeys)
public class FixPresentationSource : PresentationSource
{
protected override CompositionTarget GetCompositionTargetCore()
{
return null;
}
public override Visual RootVisual { get; set; }
public override bool IsDisposed { get { return false; } }
}
I'm writing a desktop application in Visual Studio 2008 / C#
I finished (mostly) writing an engine which generates a working schedule for the week for a small company; a form of a course-scheduling problem
Right now I'm designing a form in which the user can determine the initial parameters, or criteria, for the engine to adhere to (as some settings are optional)
I've got a class named EngineParameters, which holds all of those settings.
For the purpose of databinding, I created a bndEngineParameters class, which encapsulates all the relevant fields with getters and setters
public class bndEngineParameters
{
private engineParameters _parameters;
public bndEngineParameters(engineParameters ep)
{
this._parameters = ep;
}
public bool avoidGrouping
{
get { return _parameters.avoidGrouping; }
set { _parameters.avoidGrouping = value; }
}
public bool avoidWeekends
{
get { return _parameters.avoidWeekends; }
set { _parameters.avoidWeekends = value; }
}
public bool keyFlow
{
get { return _parameters.keyFlow; }
set { _parameters.keyFlow = value; }
}
public bool keyFlowAssistants
{
get { return _parameters.keyFlowAssistants; }
set { _parameters.keyFlowAssistants = value; }
}
}
It's not complete - there will be int values (maximum number of hours one can work etc.); I want those bool values to be bound to checkboxes on my form
And it's at that trivial task where I surprisingly ran into problems
Using "Add New DataSource" wizard, I created a binding source
private System.Windows.Forms.BindingSource bndEngineParametersBindingSource;
I then bound the Checked property of my Checkbox to the respective property of my binding source:
I implemented a local variable boundParameters so that I get an access to the parameters set by the user
public partial class formGenerateRota : Form
{
public bndEngineParameters boundParameters;
// (...)
public formGenerateRota()
{
InitializeComponent();
}
private void formGenerateRota_Load(object sender, EventArgs e)
{
boundParameters = new bndEngineParameters(new engineParameters());
bndEngineParametersBindingSource.Add(boundParameters);
}
// (...)
}
And what? Nothing happens. There is an bndEngineParameters object under bndEngineParametersBindingSource.Current (in run-time of course), but the avoidWeekends value never changes (when I check the checkbox on and off), and the bndEngineParametersBindingSource_CurrentItemChanged event is never fired
What's wrong?
SORRY! it does change, but only after the checkbox loses focus (after validation).
I'm stupid sometimes
If I'm doing something wrong anyway (I'm not any good with data binding), I'd very much appreciate if you point it out of course!
Two common issues:
set the DataSourceUpdateMode to OnPropertyChanged
(optional) to receive changes from the object, implement the {name}Changed event pattern or INotifyPropertyChanged
To be honest though, I'm sure most of that isn't necessary; you should just be able to say:
myCheckbox.Bindings.Add("Checked", myEngineParameters, "avoidWeekends",
false, DataSourceUpdateMode.OnPropertyChanged);
Full example:
using System;
using System.Diagnostics;
using System.Windows.Forms;
class EngineParameters {
private bool avoidWeekends;
public bool AvoidWeekends {
get { return avoidWeekends; }
set {
avoidWeekends = value;
Debug.WriteLine("AvoidWeekends => " + value);
}
}
}
static class Program {
[STAThread]
static void Main() {
Application.EnableVisualStyles();
using(Form form = new Form())
using (CheckBox myCheckbox = new CheckBox()) {
EngineParameters myEngineParameters = new EngineParameters();
myEngineParameters.AvoidWeekends = true;
form.Controls.Add(myCheckbox);
myCheckbox.DataBindings.Add("Checked", myEngineParameters, "AvoidWeekends",
false, DataSourceUpdateMode.OnPropertyChanged);
Application.Run(form);
}
}
}
Instead of this:
bndEngineParametersBindingSource.Add(boundParameters);
do this:
bndEngineParametersBindingSource.DataSource = boundParameters;