I am currently working on a little app that scrolls a message across the top of the form - nothing complex however i have ran into a issue where i can not get it to work with a toolstriplabel on my c# winform. I currently have it working by the following method using a normal label but toolstriplabels dont appear to have the .Left option i require to make it scroll. This is the code i am currently using in a timer.
private void timer1_Tick(object
sender, System.EventArgs e)
{
this.label1.Left = this.label1.Left - 1;
if (this.label1.Left + this.label1.Width < 0)
{
this.label1.Left = this.label1.Width;
}
}
Does anyone know how i can make this work with a toolstrip label as i would really like this scrolling text on a toolstrip so the user can drag it to where there require?
Thanks
How about something like this:
namespace WindowsFormsApplication7
{
public partial class Form1 : Form
{
string _labelText = "Hello out there!";
int _scrollOffset = 0;
public Form1()
{
InitializeComponent();
}
private void timer1_Tick( object sender, EventArgs e )
{
string textToDisplay = _labelText.Substring( _scrollOffset++ );
this.toolStripLabel1.Text = textToDisplay;
if ( _scrollOffset > _labelText.Length )
{
_scrollOffset = 0;
}
}
}
}
Related
The user often moves my XAF Winforms app between monitors.
However dialogs invoked by the PopUpWindowShowAction remain on the old monitor
This issue can be repeated with Dev Express's Main Demo ( although to debug it there I think I would need to get into the API code).
Run Main Demo and move the application window to the second monitor.
Select Users, right click a user and select Print Preview.
The Print Preview will appear on the first monitor.
In my similar case, my controller is
public partial class JobHeadFilterController : ViewController, IClassicController
{
public JobHeadFilterController()
{
InitializeComponent();
TargetViewNesting = Nesting.Root;
}
protected override void OnActivated()
{
base.OnActivated();
popupWindowShowFilterAction.QuickAccess = true;
}
private void popupWindowShowFilterAction_CustomizePopupWindowParams(object sender,
CustomizePopupWindowParamsEventArgs e)
{
var holder = new JobHeadFilterHolder();
var npProvider = new NonPersistentObjectSpaceProvider(XafTypesInfo.Instance, null);
var os = (NonPersistentObjectSpace)npProvider.CreateObjectSpace();
var view = Application.CreateDetailView(os, holder);
e.View = view;
}
I have tried browsing the properties of CustomizePopupWindowParamsEventArgs but cant see what to set.
I can get the main form using
var mainform = Application.MainWindow.Template as Form;
I think I need to do something like the following inside popupWindowShowFilterAction_CustomizePopupWindowParams
var template = e.Application.MainWindow.Template;
var window = new Window(Application, ); // having trouble figuring out the parameters
e.DialogController.SetWindow(window);
Studying the docs
[Update]
I tried
var window = e.Application.MainWindow;
e.DialogController.SetWindow(window);
but got an error
The 'DevExpress.ExpressApp.SystemModule.DialogController' controller
is active.
I tried making my own dialog controller inheriting from the Dev DevExpress.ExpressApp.SystemModule.DialogController but got the same error.
using System;
using System.Windows.Forms;
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.Templates;
using DevExpress.ExpressApp.Win.Templates;
namespace MyNameSpace;
public partial class CustomizeFormsWindowController : WindowController
{
public CustomizeFormsWindowController()
{
InitializeComponent();
TargetWindowType = WindowType.Child;
}
protected override void OnActivated()
{
base.OnActivated();
Window.TemplateChanged += WindowsTemplateChanged;
}
private void WindowsTemplateChanged(object sender, EventArgs e)
{
if (Window.Template is Form &&
Window.Template is ISupportStoreSettings)
((ISupportStoreSettings)Window.Template).SettingsReloaded +=
OnFormReadyForCustomizations;
}
private void OnFormReadyForCustomizations(object sender, EventArgs e)
{
if (sender is not PopupForm popupForm) return;
var mainForm = Application.MainWindow.Template as Form;
var X = mainForm.Location.X + (mainForm.Width - popupForm.Width) / 2;
var Y = mainForm.Location.Y + (mainForm.Height - popupForm.Height) / 2;
popupForm.SetDesktopLocation(X, Y);
}
protected override void OnDeactivated()
{
Window.TemplateChanged -= WindowsTemplateChanged;
base.OnDeactivated();
}
}
I have an array of pictureboxes named from B11 (co-ords 1,1) to B55 (co-ords 5,5). I would like to hide these all on startup (and in the middle of running). I was thinking of making an array of the names manually but would it be the best solution?
If they all have a common parent control, such as a panel or groupbox (or even the form):
Parent.SuspendLayout()
For Each pbox As PictureBox in Parent.Controls.OfType(Of PictureBox)()
pbox.Visible = False
Next pbox
Parent.ResumeLayout()
The Suspend/Resume-Layout() is to avoid flickering as you modify a bunch of controls at once.
You could extend the PictureBox class and use event handling to accomplish this by:
Adding a public property to the form to tell if the picture boxes should be shown or hidden.
Adding an event to the form that is raised when the show/hide picture box property is changed.
Extending the PictureBox class so that it subscribes to the event of the parent form.
Setting the visible property of the extended PictureBox class to the show/hide property of the parent form.
When the show/hide flag is changed on the parent form all of the picture boxes will change their visibility property accordingly.
Form Code:
public partial class PictureBoxForm : Form {
public PictureBoxForm() {
InitializeComponent();
this.pictureBoxesAdd();
}
private void pictureBoxesAdd() {
MyPictureBox mp1 = new MyPictureBox();
mp1.Location = new Point(1, 1);
MyPictureBox mp2 = new MyPictureBox();
mp2.Location = new Point(200, 1);
this.Controls.Add(mp1);
this.Controls.Add(mp2);
}
public event EventHandler PictureBoxShowFlagChanged;
public bool PictureBoxShowFlag {
get { return this.pictureBoxShowFlag; }
set {
if (this.pictureBoxShowFlag != value) {
pictureBoxShowFlag = value;
if (this.PictureBoxShowFlagChanged != null) {
this.PictureBoxShowFlagChanged(this, new EventArgs());
}
}
}
}
private bool pictureBoxShowFlag = true;
private void cmdFlip_Click( object sender, EventArgs e ) {
this.PictureBoxShowFlag = !this.PictureBoxShowFlag;
}
}
Extended PictureBox Code:
public class MyPictureBox : PictureBox {
public MyPictureBox() : base() {
this.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.ParentChanged += new EventHandler(MyPictureBox_ParentChanged);
}
private void MyPictureBox_ParentChanged( object sender, EventArgs e ) {
try {
PictureBoxForm pbf = (PictureBoxForm)this.Parent;
this.Visible = pbf.PictureBoxShowFlag;
pbf.PictureBoxShowFlagChanged += new
EventHandler(pbf_PictureBoxShowFlagChanged);
} catch { }
}
private void pbf_PictureBoxShowFlagChanged( object sender, EventArgs e ) {
PictureBoxForm pbf = (PictureBoxForm)sender;
this.Visible = pbf.PictureBoxShowFlag;
}
}
...or just put 'em all on a Panel, and change the panel's visibility.
We know very well how easy is too create a WPF application where user can paint a rectangle using the mouse. To do this you just create a Rectangle control and set its coordinates, you don't worry about DoubleBuffering, repainting and such stuff. Well, I'd be very happy yo use WPF for the application where user can paint different shapes, but the clients insists to be a WinForms application. So the solution here is to use the XOR or ROP operation like in old good WinAPI years and I don't really like this. This doesn't give me a nice option to move a text while in XOR mode.
So I was thinking how can I achieve same smooth painting experience in a WinForms application like I'd have in WPF. Put together such a code, where I wanted to create a separate layer where I'd paint the current shape, while leaving intact the rest of the objects. I used same technique in an iPad application and worked pretty well.
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
namespace TestPainting
{
public partial class Form1 : Form
{
private bool _isMouseDown;
private Graphics _bufferGraphics;
private Point _startPos;
private TransparentPanel _paintBuffer;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
_isMouseDown = true;
_paintBuffer = new TransparentPanel
{
Size = Size,
};
Controls.Add(_paintBuffer);
_paintBuffer.BringToFront();
_bufferGraphics = Graphics.FromHwnd(_paintBuffer.Handle);
_startPos = e.Location;
Capture = true;
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (!_isMouseDown)
return;
_bufferGraphics.Clear(Color.Transparent);
_bufferGraphics.DrawRectangle(Pens.Green, _startPos.X, _startPos.Y, e.X - _startPos.X, e.Y - _startPos.Y);
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
_isMouseDown = false;
Capture = false;
_bufferGraphics.Dispose();
Controls.Remove(_paintBuffer);
_paintBuffer.Dispose();
}
}
public class TransparentPanel : Panel
{
public TransparentPanel()
{
DoubleBuffered = true;
}
[Browsable(false)]
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x20;
return cp;
}
}
protected override void OnPaintBackground(PaintEventArgs e)
{
// Do Nothing
}
}
}
which if course doesn't work as needed. I'm getting a black panel when pressing the mouse instead of a transparent one. Plus the rectangle while is painted flickers a lot, even though I did set the DoubleBuffering stuff.
Can someone provide some better ideas of such an implementation or maybe there some other open source project where I can see how other people are doing. I'd need to have same experience as in Paint.NET, just too bad is not open source anymore. (I know I can use Reflector, and I did, but man, there is tons of code over there :) )
Thx for any ideas.
Try this (see FIX #1 and FIX #2):
private void Form1_MouseDown( object sender, MouseEventArgs e )
{
_isMouseDown = true;
_paintBuffer = new TransparentPanel
{
Size = Size,
};
Controls.Add( _paintBuffer );
_paintBuffer.BringToFront();
// FIX #1:
//
this.Refresh();
_bufferGraphics = Graphics.FromHwnd( _paintBuffer.Handle );
_startPos = e.Location;
Capture = true;
}
private void Form1_MouseMove( object sender, MouseEventArgs e )
{
if ( !_isMouseDown )
return;
//FIX #2:
// _bufferGraphics.Clear( Color.Transparent );
_bufferGraphics.Clear( this.BackColor );
_bufferGraphics.DrawRectangle( Pens.Green, _startPos.X, _startPos.Y, e.X - _startPos.X, e.Y - _startPos.Y );
}
I've figured out how to make everything red as soon as the page is finished loading:
private void webBrowser1_LoadCompleted(object sender, NavigationEventArgs e)
{
var doc = (IHTMLDocument2)webBrowser1.Document;
foreach (IHTMLElement elem in doc.all)
{
elem.style.backgroundColor = "#ff0000";
}
}
Now what if I want to make the element only change color when it's clicked? I see that elem has an onclick property, but it's type is dynamic so I don't know what to do with it. The documentation is pretty useless.
You could do it by using the HTMLDocumentClass instead of the IHTMLDocument2 interface:
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
private void webBrowser1_LoadCompleted(object sender, NavigationEventArgs e)
{
mshtml.HTMLDocumentClass doc = (mshtml.HTMLDocumentClass)webBrowser1.Document;
doc.HTMLDocumentEvents_Event_onclick += new mshtml.HTMLDocumentEvents_onclickEventHandler(OnClickHandler);
}
bool OnClickHandler()
{
mshtml.HTMLDocumentClass doc = (mshtml.HTMLDocumentClass)webBrowser1.Document;
mshtml.IHTMLWindow2 win = doc.parentWindow;
win.#event.srcElement.style.backgroundColor = "#ff0000";
return false;
}
}
The above solution, has one drawback: the onclick event does not bubble, even though false is returned (i.e. clicking at hyperlinks does not navigate to other pages).
Trying to implement drag and drop between 2 listboxes and all examples I've seen so far don't really smell good.
Can someone point me to or show me a good implementation?
Here's a sample form. Get started with a new WF project and drop two list boxes on the form. Make the code look like this:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
listBox1.Items.AddRange(new object[] { "one", "two", "three" });
listBox1.MouseDown += new MouseEventHandler(listBox1_MouseDown);
listBox1.MouseMove += new MouseEventHandler(listBox1_MouseMove);
listBox2.AllowDrop = true;
listBox2.DragEnter += new DragEventHandler(listBox2_DragEnter);
listBox2.DragDrop += new DragEventHandler(listBox2_DragDrop);
}
private Point mDownPos;
void listBox1_MouseDown(object sender, MouseEventArgs e) {
mDownPos = e.Location;
}
void listBox1_MouseMove(object sender, MouseEventArgs e) {
if (e.Button != MouseButtons.Left) return;
int index = listBox1.IndexFromPoint(e.Location);
if (index < 0) return;
if (Math.Abs(e.X - mDownPos.X) >= SystemInformation.DragSize.Width ||
Math.Abs(e.Y - mDownPos.Y) >= SystemInformation.DragSize.Height)
DoDragDrop(new DragObject(listBox1, listBox1.Items[index]), DragDropEffects.Move);
}
void listBox2_DragEnter(object sender, DragEventArgs e) {
DragObject obj = e.Data.GetData(typeof(DragObject)) as DragObject;
if (obj != null && obj.source != listBox2) e.Effect = e.AllowedEffect;
}
void listBox2_DragDrop(object sender, DragEventArgs e) {
DragObject obj = e.Data.GetData(typeof(DragObject)) as DragObject;
listBox2.Items.Add(obj.item);
obj.source.Items.Remove(obj.item);
}
private class DragObject {
public ListBox source;
public object item;
public DragObject(ListBox box, object data) { source = box; item = data; }
}
}
the proper way to do a drag-drop control in .net is by running code in the 2nd control's DragDrop event handler.
It may "smell" weird, but this is how it works in .NET.
Google gave this: http://www.codeproject.com/KB/dotnet/csdragndrop01.aspx
It seems a pretty reasonable tutorial. If it smells bad, I think that's more to do with the API for drag and drop being awkward to use rather than the tutorial itself being poor.