c# - Bad user control scaling for higher screen DPI -
i have user control called labeledcombobox
consist of tablelayoutpanel
(tlp
) contains 2 columns - in first column there label
control, in second - combobox
.
generally have done make control dpi-aware still behaves bad dpi > 96. ok when font size control not changed (the same in design / runtime, here 9.75). when increase font size 9.75 11 or 12, user control not scaled , gets cropped @ bottom when displayed on dpi > 96.
below screen of 3 examples different font size, starting left: 9.75 (same in design), 11, , 12.
here how code designer looks like:
private void initializecomponent() { this.tlp = new system.windows.forms.tablelayoutpanel(); this.combobox = new system.windows.forms.combobox(); this.label = new system.windows.forms.label(); this.tlp.suspendlayout(); this.suspendlayout(); // // tlp // this.tlp.autosize = true; this.tlp.autosizemode = system.windows.forms.autosizemode.growandshrink; this.tlp.backcolor = system.drawing.color.steelblue; this.tlp.columncount = 2; this.tlp.columnstyles.add(new system.windows.forms.columnstyle(system.windows.forms.sizetype.absolute, 100f)); this.tlp.columnstyles.add(new system.windows.forms.columnstyle(system.windows.forms.sizetype.absolute, 100f)); this.tlp.controls.add(this.combobox, 1, 0); this.tlp.controls.add(this.label, 0, 0); this.tlp.dock = system.windows.forms.dockstyle.fill; this.tlp.font = new system.drawing.font("segoe ui", 9.75f, system.drawing.fontstyle.regular, system.drawing.graphicsunit.point, ((byte)(238))); this.tlp.forecolor = system.drawing.color.white; this.tlp.location = new system.drawing.point(0, 0); this.tlp.name = "tlp"; this.tlp.rowcount = 1; this.tlp.rowstyles.add(new system.windows.forms.rowstyle()); this.tlp.size = new system.drawing.size(200, 30); this.tlp.tabindex = 74; // // combobox // this.combobox.backcolor = system.drawing.color.white; this.combobox.displaymember = "name"; this.combobox.dock = system.windows.forms.dockstyle.fill; this.combobox.drawmode = system.windows.forms.drawmode.ownerdrawfixed; this.combobox.dropdownstyle = system.windows.forms.comboboxstyle.dropdownlist; this.combobox.flatstyle = system.windows.forms.flatstyle.flat; this.combobox.font = new system.drawing.font("segoe ui", 9.75f, system.drawing.fontstyle.regular, system.drawing.graphicsunit.point, ((byte)(238))); this.combobox.formattingenabled = true; this.combobox.location = new system.drawing.point(102, 2); this.combobox.margin = new system.windows.forms.padding(2); this.combobox.name = "combobox"; this.combobox.size = new system.drawing.size(96, 26); this.combobox.drawitem += new system.windows.forms.drawitemeventhandler(this.combobox_drawitem); this.combobox.selectedindexchanged += new system.eventhandler(this.combobox_selectedindexchanged); this.combobox.datasourcechanged += new system.eventhandler(this.combobox_datasourcechanged); // // label // this.label.autosize = true; this.label.backcolor = system.drawing.color.steelblue; this.label.dock = system.windows.forms.dockstyle.fill; this.label.font = new system.drawing.font("segoe ui", 9.75f, system.drawing.fontstyle.regular, system.drawing.graphicsunit.point, ((byte)(238))); this.label.location = new system.drawing.point(2, 2); this.label.margin = new system.windows.forms.padding(2); this.label.name = "label"; this.label.size = new system.drawing.size(96, 26); this.label.tabindex = 59; this.label.text = "[label]"; this.label.textalign = system.drawing.contentalignment.middleleft; // // labeledcombobox // this.autoscaledimensions = new system.drawing.sizef(96f, 96f); this.autoscalemode = system.windows.forms.autoscalemode.dpi; this.autosize = true; this.autosizemode = system.windows.forms.autosizemode.growandshrink; this.backcolor = system.drawing.color.steelblue; this.controls.add(this.tlp); this.name = "labeledcombobox"; this.size = new system.drawing.size(200, 30); this.tlp.resumelayout(false); this.tlp.performlayout(); this.resumelayout(false); this.performlayout(); }
i use extension method re-draw content of combobox
:
public static class comboboxext { public static void drawcustomitem(this combobox cb, string item, drawitemeventargs e) { var fillcolor = ((e.state & drawitemstate.selected) == drawitemstate.selected) ? color.powderblue : color.white; e.graphics.fillrectangle(new solidbrush(fillcolor), e.bounds); e.graphics.drawstring(item, e.font, new solidbrush(color.black), new point(e.bounds.x, e.bounds.y)); } }
code labeledcombobox
:
public partial class labeledcombobox : usercontrol { double dpi = graphics.fromhwnd(intptr.zero).dpix / 96.0; public labeledcombobox() { initializecomponent(); } public labeledcombobox(string name) { initializecomponent(); name = name; } [browsable(true)] [category("labeledcombobox")] public float fontsize { { return label.font.sizeinpoints; } set { label.font = combobox.font = new font(label.font.fontfamily, value, graphicsunit.point); invalidate(); } } [browsable(true)] [category("labeledcombobox")] public int labelwidth { { return (int)tlp.columnstyles[0].width; } set { tlp.columnstyles[0].width = convert.toint32(dpi * value); invalidate(); } } [browsable(true)] [category("labeledcombobox")] public int comboboxwidth { { return (int)tlp.columnstyles[1].width; } set { tlp.columnstyles[1].width = convert.toint32(dpi * value); invalidate(); } } [browsable(true)] [category("labeledcombobox")] public string comboboxdisplaymember { { return combobox.displaymember; } set { combobox.displaymember = value; invalidate(); } } [browsable(true)] [category("labeledcombobox")] public object[] comboboxitems { { return combobox.datasource object[]; } set { combobox.datasource = value; invalidate(); } } [browsable(true)] [category("labeledcombobox")] public string labeltext { { return label.text; } set { label.text = value; invalidate(); } } [browsable(false)] public object selecteditem { get; set; } public delegate void selecteditemchangedhandler(object sender, labeledcomboboxitemselectedeventargs e); public event selecteditemchangedhandler selecteditemchanged; private void combobox_drawitem(object sender, drawitemeventargs e) { if (e.index >= 0) { selecteditem = combobox.items[e.index]; combobox.drawcustomitem(selecteditem.gettype().getproperty(combobox.displaymember).getvalue(selecteditem, null) string, e); } } private void combobox_selectedindexchanged(object sender, system.eventargs e) { if (combobox.selectedindex >= 0) { selecteditem = combobox.items[combobox.selectedindex]; selecteditemchanged?.invoke(this, new labeledcomboboxitemselectedeventargs { selecteditem = selecteditem }); } } private void combobox_datasourcechanged(object sender, system.eventargs e) { if (combobox.items.count > 0) { combobox.selectedindex = 0; } }
why control cropped when shown on high dpi's ? how fix this? highly appreciated.
update: screens 96 , 150 dpi - undocked combobox
Comments
Post a Comment