c# ListView Tiles view always appears as Largeicons view [duplicate] - c#

I have a inherited Listview which standard has to be in Tile Mode. When using this control, the DrawItem gives e.bounds which are clearly bounds of largeIcon view ?? When debugging to check the view it is actually set to, it says it's in Tile view ?? Yet e.DrawText draws LargeIcon view ??
......... Edit: .................
This seems only to happen when the control is placed upon another usercontrol?
......... Edit 2: .................
It gets stranger ... When i add buttons next to the list to change the view at runtime, "Tile" is the same as "LargeIcon", and "List" view is the same as "SmallIcons" ??? I've also completely removed the ownerdraw ...
.......... Edit 3: .................
MSDN Documentation:
Tile view
Each item appears as a full-sized icon
with the item label and subitem
information to the right of it. The
subitem information that appears is
specified by the application. This
view is available only on Windows XP
and the Windows Server 2003 family.
On earlier operating systems, this value is ignored and the ListView
control displays in the LargeIcon
view.
Well I am on XP ?!?
...... Edit 4 .....................
Holy mother of strangeness ...
We are now at the point we've completely stripped down EVERYTING ... We have a standard listview on a form, manually filled with 3 values. No Ownerdraw. It is set to Tile.
When we start this form, the list is drawn as LARGEICON.
Now, we start another blank solution, copy this exact same form to the new project, start debug and low and behold .. it is drawn in TILE view ????
... help ...
public class InheritedListView : ListView
{
//Hiding members ... mwuahahahahaha //yeah i was still laughing then
[BrowsableAttribute(false)]
public new View View
{
get { return base.View; }
}
public InheritedListView()
{
base.View = View.Tile;
this.OwnerDraw = true;
base.DrawItem += new DrawListViewItemEventHandler(DualLineGrid_DrawItem);
}
void DualLineGrid_DrawItem(object sender, DrawListViewItemEventArgs e)
{
View v = this.View;
//**when debugging, v is Tile, however e.DrawText() draws in LargeIcon mode,
// e.Bounds also reflects LargeIcon mode ???? **
}
................................
This code behaves differently at different solutions:
private void InitializeComponent()
{
System.Windows.Forms.ListViewItem listViewItem1 = new System.Windows.Forms.ListViewItem("fhsdhdsfhsdfhs");
System.Windows.Forms.ListViewItem listViewItem2 = new System.Windows.Forms.ListViewItem("fdshdsfhdsfhsd");
System.Windows.Forms.ListViewItem listViewItem3 = new System.Windows.Forms.ListViewItem("hdshsdfhsdfhsdfsdfsdf");
this.listView1 = new System.Windows.Forms.ListView();
this.SuspendLayout();
//
// listView1
//
this.listView1.Items.AddRange(new System.Windows.Forms.ListViewItem[] {
listViewItem1,
listViewItem2,
listViewItem3});
this.listView1.Location = new System.Drawing.Point(36, 12);
this.listView1.Name = "listView1";
this.listView1.Size = new System.Drawing.Size(487, 242);
this.listView1.TabIndex = 2;
this.listView1.TileSize = new System.Drawing.Size(480, 50);
this.listView1.UseCompatibleStateImageBehavior = false;
this.listView1.View = System.Windows.Forms.View.Tile;
//
// TestControl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(595, 712);
this.Controls.Add(this.listView1);
this.Name = "TestControl";
this.Text = "TestControl";
this.ResumeLayout(false);
}
#endregion

OK, we found it. The magic spell is:
Application.EnableVisualStyles();
We skipped this line of code to test our form.
If you don't call this method before you create your form with your listview, TILE view gets drawn as LARGEICON.
Seems totally logical ... :-(
http://blogs.msdn.com/rprabhu/archive/2003/09/28/56540.aspx
Q What does Application.EnableVisualStyles actually do?
Windows XP ships with two versions of the Common Controls Library (comctl32.dll) - versions 5.8 and 6.0. v5.8 renders controls in the "Classic" style that you get on Windows NT/2000 and Windows 9x. v6.0 renders controls using the XP Visual Styles look and feel. Since most Windows Forms controls are based on comctl32, how they are rendered depends on which version of comctl32 is used to do the rendering. By default, v5.8 is used to render the client area of the app and v6.0 is used to render the non-client area. That is why you see the title bar and window borders automatically render "themed", while the controls (like Button, TextBox, ListView, ComboBox and so on) have the classic look by default.
In v1.0 of the Framework, the way to get visual styles in a Windows Forms app was to ship a manifest file with the app, that has information in it to indicate that v6.0 of comctl32 should be used for rendering. While this works fine, many developers felt it cumbersome to author, maintain and deploy manifest files. They felt the need to be able to do this programmatically. Now, the Platform SDK does provide API to do this. Basically, you need to create and activate an Activation Context that has pretty much the same DLL redirection information in it as the manifest file. The Activation Context API can be used to do this in a way suitable to your application.
If you take a look at these API, you will probably notice that they aren't very easy to use. While the advanced developers may like to tinker around with activation contexts, it is probably not something a developer who wants some "quick and dirty" code to get visual styles will do. So the Windows Forms team decided to wrap these API and expose a simple method that developers could call, that would isolate them from these complexities. So, essentially, when you call Application.EnableVisualStyles, we set up an activation context around the application's message loop, so that comctl32 function calls can be properly redirected to comctl32 v6.0. That way, you don't need to include a manifest with your app.

Related

How do I add access rights to my c# windows forms application?

First of all, I am really sorry if the question has been asked somewhere already but I couldn't find an answer anywhere at all after looking. I am fairly new to coding as well so sorry if it isn't actually possible or something.
I have created a windows forms application in c# with multiple panels that themselves contain elements like textboxes and labels. For example, I have a chat panel and a calendar panel. I would like to somehow build access rights into this based on a user's privileges (access levels are stored in a database that is already connected to the application). Ideally, I would like that once the user logs in, the panels are then initialized and created as (from a security point of view) this would be better.
I can't really provide screenshots or much code as it is for an assessed piece of work that I am not allowed to put on the internet.
Thanks so much in advance :)
If i got you right then what you want to do is if(userHasSomePermission) { CreateComponent }; instead of creating it before and if user doesn't have permission disable/hide it
If this is the case it is not much of science but it is bit tricky.
Inside your Form constructor you have InitializeComponents() method which is method that is stored in you Form.Designer.cs file. Inside that file you are creating your controls.
What you can do is create more methods inside your Form.cs like
private void CreatePanel1()
{
Panel p = new Panel();
p.Location = new Point(3, 3);
p.Size = new Size(50, 50);
p.BackgroundColor = Color.Black;
this.Controls.Add(p);
}
and then inside your constructor call it if needed:
public Form()
{
InitializeComponents();
if( checkIfUserHavePermission )
CreatePanel1();
}
This way components inside our method will be create only if needed.
Tricky part of this is that you will not see components inside designer window since only components that are located in Form.Designer.cs/InitializeComponents() are drawn inside it. So any change you want to make will need to be done by hand through code.
Otherwise if you are concerned about security and do not want just to hide/disable some control, you could remove it if needed.
So you could use Tag property of each control and add let's say Admin_C to each control's Tag which is meant only to admins and then do this:
public Form()
{
InitializeComponents();
if(userIsNotAdmin)
{
foreach (Control item in this.Controls)
{
if(item.Tag.ToString() == "Admin_C")
this.Controls.Remove(item);
}
}
}

LayoutParams change only takes effect in fullscreen

im using Xamarin with MvvmCross.
Ive done a FragmentDialog with a recyclerView inside, the list is populated via bindings on xml file, so i have no adapter and i should keep it this way.
If im not wrong, theres no built in way to make the recyclerView take only the size needed for its content, this should not be a problem, but in this case i need the list to start from bottom...
So i did this (its a custom fullscreen dialog) :
MvxRecyclerView list = Dialog.FindViewById<MvxRecyclerView>(Resource.Id.recyclerview);
list.LayoutChange += List_LayoutChange;
Then in layoutChange
private void List_LayoutChange(object sender, View.LayoutChangeEventArgs e)
{
MvxRecyclerView list = Dialog.FindViewById<MvxRecyclerView>(Resource.Id.recyclerview);
int itemHeight = list.GetChildAt(0).Height;
if (itemHeight != 0)
{
ViewGroup.LayoutParams prms = list.LayoutParameters;
prms.Height = itemHeight * list.GetAdapter().ItemCount;
list.LayoutParameters = prms;
list.LayoutChange -= List_LayoutChange;
list.RequestLayout();
}
}
That was working fine, the list get exactly the height needed and the list looks like it starts from bottom.
Now the client tell me that he doesnt like the fullscreen dialog and wants the status bar, i think that should be easy, just to remove this line at the dialog creation right?
dialog.Window.AddFlags(WindowManagerFlags.Fullscreen);
But looks like its not that easy, when the dialog its not fullscreen the layoutParams change seems to have no effect, it just dont do nothing.
My method is being called and i get the right item height, it just dont change the recyclerview height.
Notice that setting fullscreen at creation and clearing the flag after the recyclerview params change works
So looks like it only works during fullscreen mode.
Can someone throw some light at this?
Thanks in advance.
As you said, RecyclerView was not aware of its size.
Since last update to the support lib, it is !
http://android-developers.blogspot.fr/2016/02/android-support-library-232.html
The RecyclerView widget provides an advanced and flexible base for creating lists and grids as well as supporting animations. This release brings an exciting new feature to the LayoutManager API: auto-measurement! This allows a RecyclerView to size itself based on the size of its contents. This means that previously unavailable scenarios, such as using WRAP_CONTENT for a dimension of the RecyclerView, are now possible. You’ll find all built in LayoutManagers now support auto-measurement.
I would suggest to wait for the Xamarin wrapped lib (there is already a beta https://www.nuget.org/packages/Xamarin.Android.Support.v4/23.2.0-beta1)

Coded UI tests not correctly finding my control

I'm busy running a proof of concept on what should be a very basic coded UI test.
My application is Winforms, I have a form that allows you to log in to the application.
Here 2 controls exist called _textUsername and _textPassword respectively.
To simplify the whole thing, I want playback to be able to double click the username text field (_textUsername).
However, during playback the _textPassword is selected.
I've tried to adjust the search criteria to include the control name , but then it fails to find the control at all and fails.
My question is simple: I have 2 controls on my form : _textUsername and _textPassword, UI coded tests seems to always find the _textPassword, how can I get it to find the other text box instead?
Try manually coding the controls. You can use the UI Test Builder to find the search properties. inspect.exe is also useful. Sometimes the properties aren't what you expect.
// Controls
WinWindow logonWindow = new WinWindow();
WinEdit _textPassword = new WinEdit(logonWindow);
WinEdit _textUsername = new WinEdit(logonWindow);
// Add search properties and configurations
logonWindow.SearchProperties[WinWindow.PropertyNames.Name] = "Main Window Name";
logonWindow.SearchConfigurations.Add(SearchConfiguration.AlwaysSearch);
_textPassword.SearchProperties[WinEdit.PropertyNames.Name] = "Password";
_textPassword.SearchConfigurations.Add(SearchConfiguration.AlwaysSearch);
_textUsername.SearchProperties[WinEdit.PropertyNames.Name] = "Username";
_textUsername.SearchConfigurations.Add(SearchConfiguration.AlwaysSearch);
// Identify each control
logonWindow.DrawHighlight();
_textPassword.DrawHighlight();
_textUsername.DrawHighlight();
This turned out to be wrong versions in DevExpress between the client application and the test runner code.

How to Override Application Bar Theme using Jeff Wilcox's PhoneThemeManager

I have recently added Jeff Wilcox's PhoneThemeManager to my app, which works great, although I am having problems changing the application bar buttons to the color I wish to use. My app design specifications require using the Light Theme. The problem I am having is that when the device is already in light theme, upon application loading the appbar foreground is the correct color because the PhoneThemeManager does not overwrite any values, although when in dark theme the appbar foreground values are black (which mimics the default foreground settings in the light theme).
According to his website, "If you have code in your app like “var ab = new ApplicationBar”, beware that that application bar will take on the system’s actual theme colors by default, and not the overridden light/dark coloring that happens with the app.
If you need to new up an ApplicationBar, you should use the convenience method of ThemeManager.CreateApplicationBar() or use the extension method on app bar that I added, MatchOverriddenTheme, to set the color values."
I'm not sure how to implement this to get custom appbar button colors.
I've done the following
public App()
{
// Global handler for uncaught exceptions.
UnhandledException += Application_UnhandledException;
// Standard Silverlight initialization
InitializeComponent();
// Phone-specific initialization
InitializePhoneApplication();
ThemeManager.ToLightTheme();
// Other code that might be here already...
}
And in my MainPage appbar I wish to change the buttons accordingly
private void BuildLocalizedApplicationBar()
{
// Set the page's ApplicationBar to a new instance of ApplicationBar.
ApplicationBar = new ApplicationBar();
ApplicationBar.ForegroundColor = Color.FromArgb(255, 35, 85, 155);
//Not sure where or how to use this?
ApplicationBar.MatchOverriddenTheme(); //to override ThemeManager defaults
//Create appbar buttons
...
}
Any ideas?

How do I make a tray-icon-only C# application in MonoMac (no dock icon)?

I am trying to create an application that will have a tray icon only, and not appear in the taskbar. (similar to Dropbox) I need to create both Windows and Mac version of the application, so I tried using MonoMac to create the Mac front-end.
What is the best way to create a tray-only application in MonoMac?
All the resources I have found say to do one of two things:
Add <key>LSUIElement</key><string>1</string> to the Info.plist file.
Add the following code to the FinishedLaunching event in the AppDelegate class: NSApplication.SharedApplication.ActivationPolicy = NSApplicationActivationPolicy.Accessory;
I have tried all combinations of these two, but it seems that as soon as I try to instantiate a C# System.Timers.Timer, the icon reappears in the dock at the bottom of the screen. Am I missing something about how OSX handles background applications?
What am I doing wrong? Is there a better way to make a background application that has an upper tray icon but no bottom dock icon in OSX?
(This is very similar to this SO question, but that question was from a couple years ago and was never fully answered, so I'm hoping there might be a more complete answer out there.)
Here's the code I have so far:
public partial class AppDelegate : NSApplicationDelegate
{
MyServiceObject currentServiceObject;
public AppDelegate () { }
public override void FinishedLaunching (NSObject notification)
{
// Construct menu that will be displayed when tray icon is clicked
var notifyMenu = new NSMenu();
var exitMenuItem = new NSMenuItem("Quit My Application",
(a,b) => { System.Environment.Exit(0); }); // Just add 'Quit' command
notifyMenu.AddItem(exitMenuItem);
// Display tray icon in upper-right-hand corner of the screen
var sItem = NSStatusBar.SystemStatusBar.CreateStatusItem(30);
sItem.Menu = notifyMenu;
sItem.Image = NSImage.FromStream(System.IO.File.OpenRead(
NSBundle.MainBundle.ResourcePath + #"/notify-icon.icns"));
sItem.HighlightMode = true;
// Remove the system tray icon from upper-right hand corner of the screen
// (works without adjusting the LSUIElement setting in Info.plist)
NSApplication.SharedApplication.ActivationPolicy =
NSApplicationActivationPolicy.Accessory;
// Start running the program -- If I comment out then no dock icon appears
currentServiceObject = new MyServiceObject();
}
}
I found the problem, and it wasn't related to the application settings at all. Evidently, there are some operations that MacOS does not allow an 'Agent applications' to perform. As soon as one of those methods is called, the application is forced to appear in the dock. The code that was tripping up my application was a call to:
System.Windows.Forms.Cursor.Position.ToString()
Removing that line, and replacing it with the following MonoMac method allowed the application to remain hidden:
NSEvent.CurrentMouseLocation.ToString()
I was able to get this working by setting the value of "Application is agent (UIElement)" key to 1 in the info.plist file. Even though it should be a BOOL value, MonoDevelop makes it a string, but setting it to 1 seems to work. You can also set an empty string the for the "Icon file" but it's not necessary.

Categories