I want to subclass the ListBox control and set the LBS_OWNERDRAWVARIABLE style. Subclassing is no problem and I can get messages through my own WndProc. (Actually I subclass the ListBox's parent in this case, as it is what is supposed to receive the WM_MEASUREITEM and WM_DRAWITEM messages). The problem is that I never get WM_MEASUREITEM or WM_DRAWITEM messages and the control continues to paint itself.
Both styles should be supported in WM5.0 and up:
WinCE3.0 supports neither: http://msdn.microsoft.com/en-us/library/ms959988.aspx
WinCE5.0 supports both: http://msdn.microsoft.com/en-us/library/aa453299.aspx
Even LBS_OWNERDRAWFIXED would be a start, but I can't get either to work.
My best guess is that the LBS_OWNERDRAWx style needs to be set at CreateWindowEx() time, as SetWindowLong() doesn't seem to change it. If that's the case, CF doesn't expose any methods that let me override window creation, and also doesn't expose anything like CreateParams (in full framework) or PreCreateWindow() that allows modifying the window-style before creation. (They're all there in the Control class but they're internal, so not accessible).
Has anyone managed to successfully do owner-drawing (even FIXED) using the actual Windows ListBox control on CF? Alternately, has anyone figured out a way to override the window-styles passed to CreateWindowEx() in a Control-based control? If so, please share your secrets :-)
Note: I do not want to create a list control from scratch; I can do that and there are various good examples of that out there, but that's not what this question is about.
CF2.0; WM6.1.
Related
UPDATE: So, I have a solution to my immediate problem. I haven't succeeded in making "my own" TreeView class. But, the reason I wanted to do that was because controls based on ButtonBase don't function in a Popup from a TreeView, and with the help of #MarkFeldman, I have found a solution that comes at it from a different angle.
The problem is that the MouseDown and MouseUp events bubble, and that bubbling crosses the logical tree boundary between the Popup and its owner. So, when you click on something hosted inside the Popup, the TreeViewItem and TreeView that ultimately own the Popup get to hear about it. This then triggers code inside the TreeView that checks, "Do I have focus?", and if not, helpfully sets focus back to itself -- but being a separate logical tree, the Popup has its own focus context, and so this effectively steals focus from the Button control while it is in the middle of processing a click. The Button responds to this by ignoring the click.
This erroneous handling in the TreeView only happens when MouseDown and MouseUp events reach it. What if there were a way to prevent it from seeing those events in the first place? Well, if you intercept the PreviewMouseDown and PreviewMouseUp events and mark them Handled, then the framework doesn't generate MouseDown and MouseUp events to begin with.
Looking at the Reference Source, it looks like ButtonBase's click handling is tied up in a couple of protected methods:
https://referencesource.microsoft.com/#PresentationFramework/src/Framework/System/Windows/Controls/Primitives/ButtonBase.cs,414
https://referencesource.microsoft.com/#PresentationFramework/src/Framework/System/Windows/Controls/Primitives/ButtonBase.cs,478
This means you can call them from your own subclasses! So, instead of making "my own" TreeView where all controls behave properly, instead I can make "my own" CheckBox that works properly in a Popup from a TreeView. Since all of the actual click handling is directly accessible, and the events it normally responds to use the same EventArgs type as the Preview events, and on top of it the default handling takes care of marking the events as Handled, the entire implementation boils down to this:
public class CheckBoxThatWorks : CheckBox
{
protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e) => base.OnMouseLeftButtonDown(e);
protected override void OnPreviewMouseLeftButtonUp(MouseButtonEventArgs e) => base.OnMouseLeftButtonUp(e);
}
Nice!
ORIGINAL QUESTION:
I need to make a clone of the TreeView WPF class -- a copy of the control that runs out of my own code. (There is a bug in the control and Microsoft doesn't seem to deem it high-enough priority to fix, and it makes it completely impossible to host buttons (including check boxes and radio buttons) within pop-ups shown from TreeViewItems. link)
I am running into serious difficulties with the amount of internal shenanigans Microsoft has undertaken in the implementation of base WPF controls. A couple of issues I've bumped into:
Controls have a property HandlesScrolling that allows them to take over basic scrolling handling from ScrollViewer. But, it's marked internal, making it seemingly impossible for me to have a control of my own that does its own handling of scrolling from keyboard input. I was going to try having my TreeView handle keyboard scrolling in OnPreviewKeyDown instead of OnKeyDown, so that it can prevent KeyDown events from being raised for the keys it intercepts. I haven't gotten far enough to know what caveats there might be about this.
The Visual States system allows you to declare what styles should be applied when different states are entered, but actually entering states seems to be tied up in the virtual method ChangeVisualState on the Control type. All controls that want to switch between visual states can override this method and inspect their state to determine which Visual State should be shown. Oh wait. They can't because the method is internal! Apparently only Microsoft gets to create controls that set their own visual states??
Are there any strategies I can use to work around these limitations, or am I just completely out of luck?
I'm trying to fire a TriggerAction in response to a RoutedCommand passing through a control which doesn't otherwise handle it. The problem is that as far as I can tell there is no such thing as "CommandTrigger".
This is the closest I've come to the functionality I want:
<MyControl.Triggers>
<EventTrigger xmlns:in="clr-namespace:System.Windows.Input;assembly=PresentationCore"
RoutedEvent="in:CommandManager.PreviewExecuted">
<SoundPlayerAction Source="foo"/>
</EventTrigger>
</ui:Sidebar.Triggers>
The sound is played whenever a command passes though MyControl, but it's not possible to specify which command to fire in response to. So close...
This wouldn't be such a problem if it weren't for the non-extensibility of the Trigger/Action system. According to someone on MSDN the necessary methods and constructors are internal.
Things I have tried:
I am aware of the extensible Blend class System.Windows.Interactivity.TriggerBase<T>, and in fact I've already created my own custom class based on it which does exactly what I want. Unfortunately none of that is an option as my target environment doesn't implement it.
I am also aware that it would be trivial to add a CommandBinding to the control and avoid setting e.Handled = true, but the whole point of this exercise is to avoid code-behind.
how to get a popin effect in silverlight on fly (in c# and not in XAML). by popin effect effect I mean:
Lets suppose I have two containers (a container could be a grid, pane etc) aligned vertically and theres a button on top on. On pressing the button an another container would emerge (which was invisible till now) from the top container and would slide down the already existing below container slowly.
I need the code syntax and not any already existing custom or standard component for this.
Thanks...
The scenario you described look like job for 'DataState behavior'. I usually create 2 'States' under 'Default states' such as: NormalState (the 'default ' state) and 'WorkingState' (that's include 'Busy' icon and my be fade-out screen a little bit) or even use FluidMove or Styoryline as in your example. Then create a simple public bool IsWorking {get;set;} property and attach 'DateState' behavior to it's boolean answer. So in case when IsWorking is 'true' show/run 'WorkingState' and in case of 'false' show 'NormalState'.
It's very easy to set automatically in GUI/Blend. It follows principles of MVVM pattern and testable.
The state change mechanism has 'TransitState' property - most of them build-in but very flexible. You can create a StoryLine as starting point of 'WorkingState' and slide the Components there (It's different state so you can set 'Visible' and other properties without changing it globally or managing state in code logic). You also can create independent Storyline and run it on some event rising from code but again - the preferred way it's to use DateState behavior.
Is it possible to modify NotifyIcon behavior to AlwaysShow in C#? A code snippet would be greatly appreciated:) Thanks in advance...
Cheers
---edited
One of our clients said quote "it seems necessary to customise icons to always show". What he meant was that he has to do it manually by r-clicking on task bar then click on Properties -> Task Bar -> Customize Notifications and then you can set behavior to Always Show / Always Hide / Hide when inactive for each taskbar icon on the list.
Can you do that programically in C#?
I want to ensure that my NotifyIcon is ALWAYS visible. I'm already setting icon.Visible = true but it looks like it doesn't work for him hence the complaint.
Is there any easy way of setting the behavior by altering [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\TrayNotify] IconsStream registry value?
NotifyIcon icon = ...;
icon.Visible = true;
Edit for updated information: There shouldn't be, and if for some reason it exists, don't use it. That's the user's preference, not yours.
I'm sure it's possible with enough Registry hacking, but not at all recommended. They added the collapsing-notification-area behavior in XP because so many applications were shoving themselves in that space. Much like Start Menu pinning behavior in XP/Vista/7, the lack of a public API means you're supposed to let the user decide that sort of thing.
How can I create a Delphi TSpeedButton or SpeedButton in C# 2.0?
Using a Button and setting the TabStop property to false only works when tapping through the form...
If you need (as I did) a button that does not get selected when clicking on it, there is only one way I have found to do it.
The way I did it, was to subclass the Button class and in the constructor calling the SetStyles and thereby setting Selectable to false, like so:
public class ButtonNoFocus : Button
{
public ButtonNoFocus()
: base()
{
base.SetStyle(ControlStyles.Selectable, false);
}
}
This worked out for me, and is perfect if you e.g. have a control-panel with buttons that perform actions to a selected object...
I'm wondering if you want to create a control like a TSpeedButton, or you just need same kind of end result ...
Programming one from scratch is certainly possible, but I'd only tackle that as a learning exercise.
Assuming you want to achieve a similar end result ...
Delphi's TSpeedButton had a differences from the standard TButton that developers found useful - it was flat, didn't take focus, and it consumed fewer resources than a regular button (because it didn't have an underlying Windows Handle).
Which of these are important to you?
If you just want a flat button that doesn't accept focus, use a regular Button with FlatStyle=Flat (or PopUp) and TabStop=false. You can configure a glyph by setting either the Image property, or a combination of ImageList and ImageIndex/ImageKey.
An alternative to this would be to look for an existing button component that comes close to your needs - one place to look might be the Krypton Toolkit (free to use, see http://www.componentfactory.com/toolkit_buttoncontrols.php).
If you're wanting to reduce the number of resources consumed by your application, it's likely you'll get a better return looking elsewhere.
Back in the days of Windows 3.1 (Delphi 1) and Windows 95 (Delphi 2), the number of available handles was strictly limited, with a maximum number available system wide. Today, with Windows XP and Vista, the number of available handles is far far higher, and the number is per process, not system wide. Unless you're creating thousands upon thousands of buttons, you're very unlikely to come anywhere close to running out.
Does this help? Looks like you would have to handle the OnPaint event, and not take focus...
The regular .net 2.0 button supports part of what a TSpeedbutton Does:
The Glyph: Image
Flat : FlatStyle
It does not handle:
Down
Group
These two are related, you could inherit from the button, and ownerdraw it, adding Down and Group features.
Codeproject has an example of ownerdraw buttons.