C# Override CheckedListBox - c#

i need to override the base CheckedListBox behaviour.
it is possible to check and uncheck a CheckedListBox without any code attached to it.
i need to disable this behaviour so that i can implement custom code.
any ideas?
thanks.
.
for example:
if (ListenCheckedListBox.GetItemChecked(0))
{
ListenCheckedListBox.SetItemChecked(0, false);
}
if (!ListenCheckedListBox.GetItemChecked(0))
{
ListenCheckedListBox.SetItemChecked(0, true);
}
does not work because the controls default behaviour already does this anyway.
hopefully you can understand my issue now.

You can create your own CheckedListBox by inheriting from the built-in class and overriding the relevant methods.
As I understand your question, you don't want the items to be selected when the user clicks them, you want to control the selection entirely from your code.
To do this, you can override the OnItemCheck method, and control the new value that is being set:
public class CheckedListBoxEx : CheckedListBox
{
protected override void OnItemCheck(ItemCheckEventArgs ice)
{
ice.NewValue = ice.CurrentValue;
}
}
This can also be done by simply handling the ItemCheck event.

ok i figured it out. i was seeing it wrong. i just handle for the checked state instead of defining it twice. once by the control second by me.
yes i was being silly!

Related

Is there a way to stop the WinForms designer defaulting to control Load event

This drives me nuts. In the Visual Studio WinForms designer, if you double-click a control it will produce a XXXX_Load handler for that control. This is never, ever, what you want. You want Click event or a Changed event or more likely to go to the existing Click event. You do NOT was a new Load event. It is worse because a double click can happen by accident. You click once, then again - bingo a Load event handler. I use a pen-tablet combo and double clicks are very easy!
Can someone tell me if there is a way to stop this happening. I would like a Click handler. I would settle for nothing happening.
One way to achieve that is inheriting the control and modifying the DefaultEventAttribute.
Specifies the default event for a component.
[DefaultEvent("Click")]
public class MyRadionButton : RadionButton {
}
But some care/extra work may need to be done when you override a control. You need to keep that in mind when using this approach.
In addition to Mehrzad's answer, you can completely disable it by passing an empty string to the DefaultEvent attribute:
[DefaultEvent("")]
public class MyCustomControl : UserControl
{
}
This works because the default control designer uses the ComponentDesigner.DoDefaultAction when the control is double clicked. By default, this uses reflection to look up the method signature of the default event. If it can't find it, it doesn't do anything.

Notify on ArrangeOverride

I have an items control with custom panel. Based on this itemsControl I am writing an Behavior (Behavior)
What I need is whenever arrange override for my ItemsPanel is called my behaviour should get notified. In my behavior I have access to the itemsControl and the itemsPanel.
One way is I can raise an event from ItemsPanel override and subscribe it in my Behavior.
But if you there is a better solution please can you suggest?
Here is how I would try to do it:
Create a "fake" control
class ArrangeNotifier : Control
{
public event EventHandler OnArrange;
protected override ArrangeOverride(blabla)
{
(OnArrange??delegate{})(blabla);
}
}
On your "OnAttached" of your behavior, create a var myNotifier = new ArrangeNotifier() that you will add to the panel AttachedObject (which obliges your behavior to be a Behavior<Panel>)
Suscribe to myNotifier.OnArrange from your behavior, and do your stuff in the handler
Do not forget to remove your fake control in "OnDettached" of your behavior
[Edit] I misread your question, I guess that this was what you suggested :)
I dont see any another way.

C# Enhanced Listbox - remembers additional attributes after postback

I'm in a situation where I need a listbox to remember after postback the attributes I've added to a number of the listitems in it. I found this solution online which appears to solve the issue but am not sure how to implement it.
List box solution
He says he wrote a class that inherits from Listbox which is fine, I've done that and have called it EnhancedListBox but how do I then apply that to the Listbox I'm using on the page?
I can't just substitute
<asp:ListBox >
with
<asp:EnhancedListBox>
but how else do I let the page know I want to use my inherited code?
Thanks.
SaveViewState and LoadViewState are virutal methods that you can override. What you want to try is creating "your own" ListBox:
class EnhancedListBox : ListBox
{
protected override object SaveViewState()
{
// code here from the tutorial
}
protected override void LoadViewState(object savedState)
{
// code here from the tutorial
}
}
This is also called "Creating a custom control", it's very common to do it this way and it gives you great flexibility.
you need to create a custom control for this
check this out http://msdn.microsoft.com/en-us/library/ms366537.aspx for the startup.

override C# TabControl add method

I would like to create a custom version of the TabControl so that when a new TabPage is added I can ensure some custom processing is performed.
The question is how do I override the TabPages.Add() method to achieve this?
thanks,
Richard
Unfortunatelly, you cannot override Add() method of TabPageCollection class. What you may try is to subscribe to TabControl.ControlAdded event in hope that it will be raised when a TabPage (which is essentially a Control as well) will be added.
You could create the custom version which inherits from the TabControl, and has a public new void Add(string) method. But if anyone casts your control back to the TabControl, they would go around your logic. You could try creating a custom control which inherits from System.Windows.Forms.Control and expose all the methods of a private TabControl, modifying the Add method as needed. This would give you much more control.

Is there an easy way to associate an event with a ListViewItem?

I have a WinForms ListView, obviously containing ListViewItems. I'd like to be able to attach a click event to each item, instead of to the entire ListView (and then trying to figure out what item was clicked). The reason for this is that I need to perform a different action based on which item was selected. The ListViewItem class seems to be very limited in this regard. Is there any way to do what I want, or am I forced to use the ListView.Click event?
I would still use the ListView Click event.
A trick I've used in these situations is to use the Tag property of a ListViewItem. It's great for storing per item data and you can put anything in it.
It may make sense to subclass ListViewItem and use virtual dispatch to select the appropriate behavior based on the selected ListViewItem in the appropriate ListView event.
E.g. (uncompiled)
public abstract class MyItems : ListViewItem
{
public abstract DoOperation();
}
public class MyItemA : MyItems
{
public override DoOperation()
{ /* whatever a */ }
}
public class MyItemB : MyItems
{
public override DoOperation()
{ /* whatever b */ }
}
// in ListView event
MyItems item = (MyItems)this.SelectedItem;
item.DoOperation();
As others have mentioned, it may also make sense to use the appropriate Tag property. Which technique you go for really depends on what your action is (and therefore where it belongs, architecturally). I assumed the subclass made more sense because you're looking for a click on a listview item, and that (to me) seems more likely to be presentation-layer b/c you're overriding some standard control behavior (which would normally just select an item) as opposed to doing something in response to behavior.
In most use cases, a ListViewItem is a representation in the UI of some object, and what you're trying to do is execute a method of the object that the ListViewItem represents when the user clicks on it. For the sake of simplicity and maintainability, you want as few things to sit between the user's mouse-click and the actual method being executed.
You can store the object in the ListViewItem's Tag property and then reference it in the Click event handler, but that results in code that's got some inherent weak points:
private void MyListView_Click(object sender, EventArgs e)
{
ListView l = (ListView)sender;
if (l.SelectedItem != null)
{
MyClass obj = l.SelectedItem.Tag as MyClass;
if (obj != null)
{
obj.Method();
}
}
}
That's a lot of casting and null-reference checking. And the really weak thing about this code is that if it turns out that Tag is null, or contains something other than a MyClass object, you don't really know where to look to find out where the problem is occurring.
Contrast it with code like this:
private void MyListView_Click(object sender, EventArgs e)
{
MyClass.ListViewClicked(sender as ListView);
}
When you're maintaining this code, you don't know how that ListViewClicked method is implemented, but at least you know where to look for it - in MyClass. And when you do, you'll see something like this:
public static void ListViewClicked(ListView listView)
{
if (listView.SelectedItem == null)
{
return;
}
if (ListViewItemLookup.ContainsKey(listView.SelectedItem))
{
ListViewItemLookup[listView.SelectedItem].Execute();
}
}
Well, that's interesting. Following the thread, how does that dictionary get populated? You find that in another method in MyClass:
private static Dictionary<ListViewItem, MyClass> ListViewItemLookup =
new Dictionary<ListViewItem, MyClass>();
public ListViewItem GetListViewItem()
{
ListViewItem item = new ListViewItem();
item.Text = SomeProperty;
// population of other ListViewItem columns goes here
ListViewItemLookup.Add(item, this);
return item;
}
(Reasonable people can disagree about whether or not it's appropriate for a class to be so closely tied to a specific form of its representation in the UI - there are those who would isolate these methods and this dictionary in a helper class instead of in MyClass itself, and depending on how hairy the rest of the problem is I might do it too.)
This approach solves a number of problems: it gives you a simple way of handling the ListView's Click event properly, which is what you asked for. But it also isolates the not-always-trivial process of creating the ListViewItem in the first place. It reduces the amount of code you'll have to move around if you refactor your form and move the ListView to another form. And it reduces the number of things that your form class needs to know about, which is generally a good thing.
Also, it's testable. Generally, the only way to test code in a UI event handler is through the UI. This approach lets you isolate all of the logic surrounding this part of the UI in something that you can unit test; the only thing you can't write a unit test for is a single line of code in the form.
I should point out that the other approach people have been suggesting - subclassing ListViewItem - is perfectly fine too. You put the logic I put in the GetListViewItem method in the class's constructor, make the MyClass instance a private property of the class, and expose a Click method that calls the method of MyClass. Pretty much the only reason I don't like it is that it still leaves you with a fair amount of code in your form that you can't really unit test:
ListView l = (ListView)sender;
if (l.SelectedItem != null)
{
MyClassListViewItem item = l.SelectedItem as MyClassListViewItem;
if (item != null)
{
item.MyClass.Method();
}
}
You might however have luck sticking a reference to a delegate or other handler in the tag field (assuming there is a tag property of a ListViewItem). You would still have to determine which ListViewItem is clicked, but you could then go straight to the tag instead of another decision structure.
You want to create a new class (or classes if there are various types), which inherits from ListViewItem, then populate your ListView with these objects (as long as they inherit from listview (even several levels of inheritence) The ListView control will take them).
Then add a click method to your custom class(es) and on the ItemClick event of your listView, just call the click method of the clicked item. (some casting may be needed)
Actually there is no way to use a ListViewItem. You have to use the ListView itself. By using the 'SelectedItems' property of the ListView you can access the selected ListViewItems.
One option is to override the ListViewItem class an implement the specific stuff in there. Then you can cast the selected item to the overridden one and perform the action.
I really don't understand the reason to do so instead of just using the regular ListView Click event, but if I were to do like you suggest I would assign an EventHandler delegate to the Tag property of each ListViewItem, then in the ListView Click event handler I would check if the ListViewItem.Tag <> null, and if so call the delegate.

Categories

Resources