I have found the following in WPF:
I have a form with AllowTransparency=true. Inside the form I put a Combobox.
I add some items to the combobox.
I run this application and click on the combobox. At first it does not seem to appear at all. On closer inspection (after adding more items) I see that it is actually appearing behind the form. If I add enough items it become visible from behind the form.
If I just change AllowTransparency=false, then all is fine.
This looks like a bug in WPF (3.5 SP1).
Any one know of a workaround for this?
Go to
https://connect.microsoft.com/dashboard/?wa=wsignin1.0
submit your feedback after searching #
https://connect.microsoft.com/VisualStudio
https://connect.microsoft.com/VisualStudio/feedback/CreateFeedbackForm.aspx?FeedbackFormConfigurationID=1160&FeedbackType=1
and mention steps to reproduce.
There was an update of 3.5sp1 but you could test,but I doubt
http://www.microsoft.com/downloads/details.aspx?familyid=6c095bba-6100-4ec9-9c54-6450b0212565&displaylang=en
AllowTransparency is slow and buggy and shouldn't be used - it's a great way to run into bug in various display drivers.
You can get almost anything you like without using AllowTrasparency, take a look at this post for examples:
http://blogs.msdn.com/wpfsdk/archive/2008/09/08/custom-window-chrome-in-wpf.aspx
Related
I have a radgridview with a GridViewToggleRowDetailsColumn and I can set the visibility of the GridViewToggleButton the way I want through the RowLoaded event for each row. It was working fine until I need to scroll horizontally. When the GridViewToggleRowDetailsColumn get out of the screen and I scroll back to it, the GridViewToggleButton are now all visible.
I tried to find any event triggered by this without success. Even the IsVisibleChanged event attached to the GridViewToggleButton seems to be triggered only on the visible one.
Does anyone faced the same issue or have any idea of what could produce this behavior ?
Edit: Found the answer. It was a virtualization issue. Adding EnableColumnVirtualization="False" in the gridview properties solved it.
https://docs.telerik.com/devtools/wpf/controls/radgridview/features/ui-virtualization
After a few minutes of research, it appears that telerik WPF GridView uses virtualization to improve performace. This means that the state of what is in the screen is retained and as things leave your viewing area they are destroyed. This frees up memory space significantly, however can have some side effects as you are experiencing.
You can set EnableColumnVirtualization=false however Telerik has provided a help article that will likely answer your question more directly while not sacrificing the performance provided by the virtualizations. A link is below and following through the steps, it looks fairly straightforward.
https://docs.telerik.com/devtools/wpf/controls/radgridview/style-selectors/cell-style-selector
The recommended approach for customizing this behavior, and not turning off the virtualization, is to use a custom column. Try inheriting from GridViewToggleRowDetailsColumn and override CreateCellElement. It is the callback for creating the visual element in the cell, which is called, more or less, at the same time as RowLoaded. Then return null for those rows that you don't want to have a button for.
I have used Confuserex to obfuscate my code which is using .net 4.5. Post compilation everything seems ok except for the behaviour of combobox (across all winforms i had in the project). The comboboxes are now showing id instead of the values as dropdowns. (Whereas these were running absolutely fine from visual studio in debug mode as well as the builds from the release mode).
In confuserex I have tried setting the preset to Aggressive, Maximum ... but same issue irrespective of whichever preset i use.
Not putting any code here as there is no issue with the code per se. This is most likely a issue in Confuserex.
Is this a known issue and does a solution exists? Please let me know if any further details are required for providing help.
There's no way to give you a singular answer, but perhaps I can steer you in the right direction:
In recently implementing ConfuserEx in a Winforms post-build event, I found that some third party controls were not displaying data correctly, or at all. Like you, I changed the preset from Aggressive to Normal, to no avail. I then went and excluded some of the methods that were binding data from obfuscation. It alleviated the problem in some cases, on a data grid view and list box, specifically. In those controls, I was receiving weird glitches like extra columns, cells rendered blank (with data present in the underlying object), et al.
All bets are off for third party controls with obfuscation - you'll never know if they will play ball or not. Sometimes you'll experience this with .Net controls as well. Obfuscation and Reflection also do not get along. Perhaps check your combo box data bind technique, and lift the obfuscation from the method where it is being populated with data, if nothing else. This is, of course, if you can live with this method being exposed. Here's one way to do it:
[System.Reflection.Obfuscation(Exclude = true)]
public void MethodYouDontWantToObfuscate()
{
//Your method code
}
Until just now I had a similar problem with WPF.
Our comboboxitems were in their own class. To solve the issue I added
[System.Reflection.Obfuscation(Exclude = true)]
in front of the class-declaration (like MoSSBerG suggested) and now everything works like a charm.
In UI Automation, when automating the toolstrip items we are facing an issue which is described below
I am adding toolstrip items as follows
this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.toolStripButton1,
this.toolStripButton2,
this.toolStripComboBox1,
this.toolStripButton3});
When running the UI Automation(System.Windows.Automation), UI automation finds the controls till toolStripButton2 (i.e) controls on the left side of toolstripcombobox is getting recognized but on the controls on the right side.(If i make the combobox to go the right most control everything works fine)
Note: In Inspect.exe tool from windows kits, all the controls are shown but when trying to access the last toolStripButton3 returns null.
Here i have attached the simplified code, the buttonCollection is expected to get 3 buttons but it gets only two in my case.
AutomationElement toolstrip = viewTab.FindFirst(TreeScope.Children,
new PropertyCondition(AutomationElement.AutomationIdProperty, "toolStrip1"));
AutomationElementCollection buttonCollection = toolstrip.FindAll(TreeScope.Children,
new PropertyCondition(AutomationElement.LocalizedControlTypeProperty, "button"));
Both ToolStripTextBox and ToolStripComboBox are showing the same behavior.
I would like know what is going wrong my approach.
I've posted one approach which would allow you to access all the buttons, in response to your question at https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/2363de9f-3bf0-48dc-a914-1eef5bcf1482/toolstriptextbox-toolstripcombobox-not-automated?forum=windowsaccessibilityandautomation.
Thanks,
Guy
I've been creating an inspection form using WPF and I need a place where users can type an unknown amount of comments (hence why I'm not using textboxes). In my WinForms version of this application, I used a DataGridView and I could enter in as much information as I wanted to. I'm looking to do the same with a DataGrid or an equivalent control in WPF.
WinForms Example
I need to be able to do the same thing in WPF but I can't seem to add any rows in the DataGrid. On top of that, when I try to check CanUserAddRows it unchecks it immediatly.
So I checked out Vincent Sigal's blog post about this issue. He mentions something interesting:
... but beware of CanUserAddRows and CanUserDeleteRows as they can appear a little magical. Their values are coerced based on other properties such as DataGrid.IsReadOnly, DataGrid.IsEnabled, IEditableCollectionView.CanAddNew, and IEditableCollectionView.CanRemove. So this is another thing to watch out for when editing. If you run into a situation where you set CanUserAddRows or CanUserDeleteRows to true but it is changed to false automatically, check that the conditions below are met.
I verified this and my DataGrid is not read-only and it is enabled. Although, I have no idea where to find the IEditableCollectionView.CanAddNew and IEditableCollectionView.CanRemove ...
I don't think my situation should require a binding event on the DataGrid since the user is supposed to enter his comments directly into the DataGrid ... Is what I'm trying to do even possible? Perhaps I should use a different control?
I have to admit that I stopped reading through your question after the first paragraph, so please forgive me if I have understood you wrong... but if you just want to enter multi line text into a TextBox in WPF, you can do it by setting a couple of properties on it:
<TextBox TextWrapping="Wrap" AcceptsReturn="True" />
For a DataGrid, you can set these properties in the DataGridTextColumn.ElementStyle and/or DataGridTextColumn.EditingElementStyle as the WPF DataGridTextColumn multi-line input post shows quite nicely.
Please let me know if I did misunderstand you.
UPDATE >>>
Ok, so I came back to read the rest of your question... answering without reading the question can be risky business on this site. It's just as well that I did too, as I see you also want to know how to use the DataGrid.
I have to start by saying... take a deep breath... WPF is very different to WinForms... very different. In WPF we manipulate data rather than UI objects, so to add a new row actually means adding a new item to a collection. You can find a complete working example on the DataGrid Class page on MSDN.
Please also view the WPF DataGrid Control page on WPF Tutorial.NET for more examples. WPF has a lot to take in for new comers and can be quite bewildering, but it's well worth the trouble when you get into it.
I have inherited a large MFC application which contains a CComboBox subclass that overrides OnPaint. Currently it does all its drawing by hand (with lines and rectangles), and renders a combo box that looks decidedly Windows 98-style. However, it otherwise works great and provides a lot of useful custom functionality that we rely on, and rewriting the entire control is probably not an option.
I would like to modernize it so that the OnPaint draws in Aero style where available (falling back to the old code when modern theming is unavailable). I've done this with some other custom controls we have, like buttons, and it works great for our purposes. I know there are some tiny behaviors that it won't get right, like gentle highlights on mouse-hover, but that's not a big deal for this app.
I have access to the CVisualStylesXP ckass, so I've already got the infrastructure to make calls like OpenThemeData, GetThemeColor or DrawThemeBackground pretty easily (via LoadLibrary so we don't force Vista as a min-system). Unfortunately, I don't know the proper sequence of calls to get a nice looking combo box with the theme-appropriate border and drop-down button.
Anyone know what to do here?
Honestly, I don't know why they originally tried to override OnPaint. Is there a good reason? I'm thinking that at least 99% of the time you are just going to want to override the drawing of the items in the ComboBox. For that, you can override DrawItem, MeasureItem, and CompareItem in a derived combo box to get the functionality you want. In that case, the OS will draw the non-user content specific to each OS correctly.
I think you best shot without diving in the depth of xp theming and various system metrics is take a look at this project: http://www.codeproject.com/Articles/2584/AdvComboBox-Version-2-1
Check the OnPaint of the CAdvComboBox class - there is a full implementation of the control repainting including xp theme related issues.
Not sure if it's the same situation - but when I faced this problem (in my case with subclassed CButtons), solving it only required changing the control declaration to a pointer and creating the control dynamically.
Let's assume that your subclassed control is called CComboBoxExt.
Where you had
CComboBoxExt m_cComboBoxExt;
You'll now have
CComboBoxExt* m_pcComboBoxExt;
And on the OnInitDialog of the window where the control is placed, you create it using
m_pcComboBoxExt = new CComboBoxExt();
m_pcComboBoxExt->Create(...)
Since this is now a pointer, don't forget to call DestroyWindow() and delete the pointer on termination.
This solved my particular problem - if your control is declared in the same way, consider giving it a try.