neděle 9. června 2013

DevExpress BarEditItem Closing-Editor at runtime to obtain entered value

I think everybody already faced problem with value in editor by DevExpress WinForms application. Usually it happens when we want to use value immediately the ENTER was pressed in EditorCell. The first action we have to do is CloseEditor, to force editor store the entered value.

The problem comes when the editor is placed into toolbar as the BarEditItem.

The BarEditItem has no CloseEditor method implemented. After short investigation I learned, that current editor is not runned under BarEditItem but by the link to BarEditItem. The BarEditItem has collection of Links, which reference all instances of this BarEditItem displayed in the menu. So if you want close the editor, you must find the correct one by Links array.

My final solution is Extension method to BarEditItem, which closes all possible linked editors (yup, little hack, but helpful).

Here is my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace DevExpress.XtraBars
{
    public static class DevExpressWinFormBarEditItemExtension
    {
        /// <summary>
        /// Extension Method. Closes all editors joined over links (BarItemLink) to BarEditItem and and close them.
        /// </summary>
        /// <param name="item"></param>
        public static void CloseAllEditors(this BarEditItem item) {
            foreach (BarEditItemLink link in item.Links.OfType<BarEditItemLink>()) { link.CloseEditor(); } 
        }
    }
}

... and here is usage in action:
        private void reibeSupOrderNr_KeyDown(object senderKeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                beiSupOrderNr.CloseAllEditors();
                addItemAccordingToolbatText();
            }
        }

neděle 17. února 2013

CSS - Exact same height and alignment of text and input text box in major browsers

This is the story about long time testing behaviour of this feature for Firefox, IE9, Chrome, Opera and Safari.
My goal was to have pretty labelled text input fields on the web site, which are connected together to one visual compact object. Finally I was successful but not for 100%. There is still browser reaction to different  fonts, font-size and browsers. But anyway, there are results with different fonts here:

As you can see, there was a goal to keep element compact in different themes, which I have in my application. May goal was also to have independent <input type="text"> element, so wished behaviour was to make automatically compacted label and text element when the label exists. If label does not exist I wanted to have same input-text, but without joining to the text (second text-item row in result).

Finally result does not work for 100% in all browsers and themes, it needs short "trimming" of the vertical padding for your exact case, to reach the same width for both elements.

Shadows and gradients is another story, so now I would like concentrate to compact fields only.

The very important to create useful cross-browser application is the html header definition:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

So, there is the testing form code here:

<div style="padding:10px; font-family: Calibri; font-size: 14px;">
<div class="lf-ui-label" 
    style="width:25%; padding-left: 10px;">Field textnbsp;</div><input 
    class="lf-ui-form-item" type="text" id="fr" name="fr" value="some value" style="width:71%" />
</div>


<div style="padding:10px; font-family: Calibri; font-size: 9px;">
Field text <input class="lf-ui-form-item" type="text" value="some other value"/>
</div>


There are defined two blocks, one contains the compact labelled text input and the second standard text input with normal unformatted text label. 

Important for this solution, is set-up font-family and font size in the parent block:

<div style="padding:10px; font-family: Calibri; font-size: 14px;">

So children elements inherits font-family and font size from the parent. For the label element I used the DIV after several test with SPAN and LABEL. Finally I learned the DIV is the best for my goal.

The label DIV is marked with class lf-ui-label and the text-input is marked with lf-ui-form-item class. The second item block is defined without the label DIV:

div.lf-ui-label {
    margin: 0px;
    font-size: inherit;
    font-weight: bold;
    background-color: #CCCCCC;
    border-width: 0px;
    display: inline-block;
    vertical-align: middle;
    overflow: hidden;
    padding-top: 4px;
    padding-bottom: 4px;
}
div.lf-ui-label + input.lf-ui-form-item {

    padding: 5px 10px 5px 10px;
    margin: 0px 0px 0px -10px;
    font-size: inherit;
    background-color: #2b55a8 !important;
    vertical-align: middle;
    border-width: 0px;
}
input.lf-ui-form-item {


    background-color: #3b3b3b;
    font-size: inherit;
    padding: 4px 7px 4px 7px;
    font-weight: bold;
    border: none 0px;
    outline: none;
}

Background colours are used as markers for particular elements.

font-size and font-weight must be inherited, to keep the same vertical size, but for my themes I used bold for all form elements, so, I defined it here.

For label is very important to keep follow styles:
margin: 0px 
border-width: 0px;
display: inline-block; - gets the DIV in line with text input element
vertical-align: middle; - important for cross browser alignment
overflow: hidden; - multi-line is not allowed

This class div.lf-ui-label + input.lf-ui-form-item is styling the input with class .lf-ui-form-item located next to DIV with .lf-ui-label. So if I put text-input next to label is styled with this class. If the text-input is not located next to .lf-ui-label is not styled. So this CSS part is taking care about compact behaviour.

For text item located next to label DIV (in css: div.lf-ui-label + input.lf-ui-form-item) is very important to keep top and bottom margin on zero: margin: 0px 0px 0px -10px;

Finally, to reach the same vertical size it is necessary to trim top and bottom padding in both classes to reach the compact effect. Commonly it is very easy for standard fonts and sizes and work it in all browsers.

There is the result from experimental solution in the JSFIDDLE:
JSFIDDLE.Net experiment link - there you can take the complete experiment code too

Experiment HTML code:



<div style="padding:10px; font-family: Calibri; font-size: 8px;">
<div class="lf-ui-label" 
    style="width:25%; padding-left: 10px;">Field text 8px&nbsp;</div><input 
    class="lf-ui-form-item" type="text" id="fr" name="fr" value="some value" style="width:71%" />
</div>

<div style="padding:10px; font-family: Calibri; font-size: 9px;">
<div class="lf-ui-label" 
    style="width:25%; padding-left: 10px;">Field text 9px&nbsp;</div><input 
    class="lf-ui-form-item" type="text" id="fr" name="fr" value="some value" style="width:71%" />
</div>

<div style="padding:10px; font-family: Calibri; font-size: 10px;">
<div class="lf-ui-label" 
    style="width:25%; padding-left: 10px;">Field text 10px&nbsp;</div><input 
    class="lf-ui-form-item" type="text" id="fr" name="fr" value="some value" style="width:71%" />
</div>

<div style="padding:10px; font-family: Calibri; font-size: 12px;">
<div class="lf-ui-label" 
    style="width:25%; padding-left: 10px;">Field text 12px&nbsp;</div><input 
    class="lf-ui-form-item" type="text" id="fr" name="fr" value="some value" style="width:71%" />
</div>

<div style="padding:10px; font-family: Calibri; font-size: 14px;">
<div class="lf-ui-label" 
    style="width:25%; padding-left: 10px;">Field text 14px&nbsp;</div><input 
    class="lf-ui-form-item" type="text" id="fr" name="fr" value="some value" style="width:71%" />
</div>

<div style="padding:10px; font-family: Calibri; font-size: 16px;">
<div class="lf-ui-label" 
    style="width:25%; padding-left: 10px;">Field text 16px&nbsp;</div><input 
    class="lf-ui-form-item" type="text" id="fr" name="fr" value="some value" style="width:71%" />
</div>

<div style="padding:10px; font-family: Calibri; font-size: 18px;">
<div class="lf-ui-label" 
    style="width:25%; padding-left: 10px;">Field text 18px&nbsp;</div><input 
    class="lf-ui-form-item" type="text" id="fr" name="fr" value="some value" style="width:71%" />
</div>

<div style="padding:10px; font-family: Calibri; font-size: 20px;">
<div class="lf-ui-label" 
    style="width:25%; padding-left: 10px;">Field text 20px&nbsp;</div><input 
    class="lf-ui-form-item" type="text" id="fr" name="fr" value="some value" style="width:71%" />
</div>

<div style="padding:10px; font-family: Calibri; font-size: 22px;">
<div class="lf-ui-label" 
    style="width:25%; padding-left: 10px;">Field text 22px&nbsp;</div><input 
    class="lf-ui-form-item" type="text" id="fr" name="fr" value="some value" style="width:71%" />
</div>

<div style="padding:10px; font-family: Calibri; font-size: 26px;">
<div class="lf-ui-label" 
    style="width:25%; padding-left: 10px;">Field text 26px&nbsp;</div><input 
    class="lf-ui-form-item" type="text" id="fr" name="fr" value="some value" style="width:71%" />
</div>


    
    
<div  style="padding:10px; font-family: Calibri; font-size: 26px;">
Field text <input class="lf-ui-form-item" type="text" value="some other value"/>
</div>




Sources: