Telerik Forums
UI for WinForms Forum
1 answer
134 views

I recently run into weird redraw problems with the Forms Designer on a Windows XP Tablet Edition PC. Turned out to be related to the hardware acceleration settings of the graphics card driver. I've read that WPF can have problems with some display drivers. Has anybody experienced the same, in particular together with the Telerik Controls?

Symptoms were:
    Controls do not draw correctly in designer mode
    Container Controls do not draw
    Cannot select the Task menu
    Controls are invisible while moving them around on a Form

Workaround for now is to disable some of the HW Acceleration Features, especially Direct Draw related Settings.

Regards
Erwin
Peter
Telerik team
 answered on 26 Oct 2010
1 answer
81 views

hi,

i have a problem in column header if i set field name contain "." or multi "_" did not display any data

please replay as soon as possible 

Emanuel Varga
Top achievements
Rank 1
 answered on 26 Oct 2010
2 answers
101 views
Hi,
I've downloaded ExCheckedListBox from CodeProject. the control extends the ability of CheckedListBox by adding DataBinding feature.I have 3 tables: Table1,2 and Table3. Here is data for them:
Table1
ID1    Name
1        name1
2        name2
3        name3
Table3
ID3    price
1        200   
2        300
3        400
Table2 (Joins Table1 and Table3)
ID1    ID3
1        1    
1        2    
2        3
Items of ExCheckedListBox are selected from Table 3.
When the user navigate records of Table1 in a RadGridView only the items which are related in Table2 must be checked. that is
when record with ID1=1 of Table1 is selected, then only price 200 and 300 must be checked in the ExCheckedListBox. Because in Table2, ID1=1 has two related records: 200(ID2=1) and 300(ID2=2) .
But how?
I've tested the Value property but I was not successfull.
Please guide me.
Emanuel Varga
Top achievements
Rank 1
 answered on 26 Oct 2010
7 answers
164 views
Hello,

I was wondering if there was a AllowClearCell property (or something similar). I don't want the user to right-click on a cell and select the Clear Value function on some on my cells. Is there a way other than the event CellValueChanged?

If the person wants to clear the value of a cell, I want him to click in it and edit the value to leave nothing in it. I want this mainly because I have code in the CellEndEdit and because I don't want the values in my ComboBoxColumn to be cleared (It must be one of the values in the list).
xclirion
Top achievements
Rank 1
 answered on 26 Oct 2010
4 answers
522 views
I have an editable grid where the first column is a combobox.

I am using gridView1.ClearSelection to clear any selection because the customer wants the grid to appear with no default selection.

However, the first cell of the first row is still selected.

I've tried everything I can think of, but nothing seems to be unselecting that first cell in the first row.

I attached a screen shot in case this is not clear.

Thanks!
Emanuel Varga
Top achievements
Rank 1
 answered on 25 Oct 2010
8 answers
265 views
Hi,
I want to add FADatePicker Component to my RadGridView but I don't know how. Here is the code which makes it possible to add FADatePicker to GridView:
using System;
using System.ComponentModel;
using System.Drawing;
using System.Globalization;
using System.Text;
using System.Windows.Forms;
using FarsiLibrary.Utils;
using FarsiLibrary.Win.Enums;

namespace FarsiLibrary.Win.Controls
{
    #region DataGridViewDateTimeCell

    public class DataGridViewFADateTimePickerCell : DataGridViewTextBoxCell
    {
        #region Fields

        private DateTime selectedDateTime;
        private static Type valueType = typeof (DateTime);
        private static Type editType = typeof (DataGridViewFADateTimePickerEditor);
        private StringAlignment verticalAlignment;
        private StringAlignment horizontalAlignment;
        private FormatInfoTypes format;
        
        #endregion

        #region Props
        
        /// <summary>
        /// FormatInfoTypes instance, used to format date to string representation.
        /// </summary>
        [Description("FormatInfoTypes instance, used to format date to string representation.")]
        [DefaultValue(typeof(FormatInfoTypes), "ShortDate")]
        public FormatInfoTypes FormatInfo
        {
            get { return format; }
            set
            {
                if (format == value)
                    return;

                format = value;
            }
        }

        public ThemeTypes Theme
        {
            get
            {
                if(DataGridView == null || EditingFADatePicker == null)
                    return ThemeTypes.Office2000;
                
                return EditingFADatePicker.Theme;
            }
            set
            {
                if(DataGridView != null && EditingFADatePicker != null)
                    EditingFADatePicker.Theme = value;
            }
        }

        public override Type EditType
        {
            get { return editType; }
        }

        public override Type ValueType
        {
            get { return valueType; }
        }

        public DateTime SelectedDateTime
        {
            get { return selectedDateTime; }
            set { selectedDateTime = value; }
        }
        
        /// <summary>
        /// Returns the current DataGridView EditingControl as a DataGridViewNumericUpDownEditingControl control
        /// </summary>
        private DataGridViewFADateTimePickerEditor EditingFADatePicker
        {
            get { return DataGridView.EditingControl as DataGridViewFADateTimePickerEditor; }
        }

        
        
        #endregion

        #region Methods

        protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex,
                                      DataGridViewElementStates cellState, object value, object formattedValue,
                                      string errorText, DataGridViewCellStyle cellStyle,
                                      DataGridViewAdvancedBorderStyle advancedBorderStyle,
                                      DataGridViewPaintParts paintParts)
        {
            if(DataGridView == null)
                return;


            // First paint the borders and background of the cell.
            base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts & ~(DataGridViewPaintParts.ErrorIcon | DataGridViewPaintParts.ContentForeground));

            Point ptCurrentCell = DataGridView.CurrentCellAddress;
            bool cellCurrent = ptCurrentCell.X == ColumnIndex && ptCurrentCell.Y == rowIndex;
            bool cellEdited = cellCurrent && DataGridView.EditingControl != null;

            // If the cell is in editing mode, there is nothing else to paint
            if (!cellEdited && value != null && !string.IsNullOrEmpty(value.ToString()))
            {
                PersianDate pd = null;
                if (value is DateTime)
                {
                    pd = (DateTime)value;
                }
                else if (value is string)
                {
                    pd = PersianDate.Parse(value.ToString());
                }

                if (pd != null)
                {
                    using (SolidBrush brFG = new SolidBrush(cellStyle.ForeColor))
                    using (SolidBrush brSelected = new SolidBrush(cellStyle.SelectionForeColor))
                    using (StringFormat fmt = new StringFormat())
                    {
                        fmt.LineAlignment = HorizontalAlignment;
                        fmt.Alignment = VerticalAlignment;
                        fmt.Trimming = StringTrimming.None;
                        fmt.FormatFlags = StringFormatFlags.LineLimit;

                        graphics.DrawString(pd.ToString(), cellStyle.Font, IsInState(cellState, DataGridViewElementStates.Selected) ? brSelected : brFG, cellBounds, fmt);
                    }
                }
            }
            
            if (PartPainted(paintParts, DataGridViewPaintParts.ErrorIcon))
                base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, DataGridViewPaintParts.ErrorIcon);
        }

        [DefaultValue("Center")]
        public StringAlignment VerticalAlignment
        {
            get { return verticalAlignment; }
            set { verticalAlignment = value; }
        }

        [DefaultValue("Near")]
        public StringAlignment HorizontalAlignment
        {
            get { return horizontalAlignment; }
            set { horizontalAlignment = value; }
        }

        private static bool IsInState(DataGridViewElementStates currentState, DataGridViewElementStates checkState)
        {
            return (currentState & checkState) != 0;
        }

        /// <summary>
        /// Little utility function called by the Paint function to see if a particular part needs to be painted. 
        /// </summary>
        private static bool PartPainted(DataGridViewPaintParts paintParts, DataGridViewPaintParts paintPart)
        {
            return (paintParts & paintPart) != 0;
        }

        /// <summary>
        /// Determines whether this cell, at the given row index, shows the grid's editing control or not.
        /// The row index needs to be provided as a parameter because this cell may be shared among multiple rows.
        /// </summary>
        private bool OwnsEditor(int rowIndex)
        {
            if (rowIndex == -1 || DataGridView == null)
                return false;

            DataGridViewFADateTimePickerEditor editor = DataGridView.EditingControl as DataGridViewFADateTimePickerEditor;
            return editor != null && rowIndex == editor.EditingControlRowIndex;
        }

        internal void SetValue(int rowIndex, DateTime value)
        {
            SelectedDateTime = value;
            if (OwnsEditor(rowIndex))
                EditingFADatePicker.SelectedDateTime = value;
        }
        
        public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
        {
            base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);
            DataGridViewFADateTimePickerEditor editor = DataGridView.EditingControl as DataGridViewFADateTimePickerEditor;

            if (editor != null)
            {
                editor.RightToLeft = DataGridView.RightToLeft;
                editor.Theme = Theme;
                string formattedValue = initialFormattedValue.ToString();

                if (string.IsNullOrEmpty(formattedValue))
                {
                    editor.SelectedDateTime = DateTime.Now;
                    editor.mv.MonthViewControl.SetNoneDay();
                }
                else
                {
                    editor.SelectedDateTime = DateTime.Parse(formattedValue);
                }
            }
        }

        #endregion
    }

    #endregion

    #region DataGridViewFADateTimePickerEditor

    public class DataGridViewFADateTimePickerEditor : FADatePicker, IDataGridViewEditingControl
    {
        private int editingControlRowIndex;
        private DataGridView editingControlDataGridView;
        private bool valueChanged;

        public DataGridViewFADateTimePickerEditor()
        {
            SelectedDateTimeChanged += new EventHandler(OnInternalSelectedDateTimeChanged);
        }

        private void OnInternalSelectedDateTimeChanged(object sender, EventArgs e)
        {
            EditingControlValueChanged = true;
            NotifyDataGridViewOfValueChange();
        }

        ///<summary>
        ///Changes the control's user interface (UI) to be consistent with the specified cell style.
        ///</summary>
        ///
        ///<param name="dataGridViewCellStyle">The <see cref="T:System.Windows.Forms.DataGridViewCellStyle"></see> to use as the model for the UI.</param>
        public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle)
        {
        }

        ///<summary>
        ///Determines whether the specified key is a regular input key that the editing control should process or a special key that the <see cref="T:System.Windows.Forms.DataGridView"></see> should process.
        ///</summary>
        ///
        ///<returns>
        ///true if the specified key is a regular input key that should be handled by the editing control; otherwise, false.
        ///</returns>
        ///
        ///<param name="keyData">A <see cref="T:System.Windows.Forms.Keys"></see> that represents the key that was pressed.</param>
        ///<param name="dataGridViewWantsInputKey">true when the <see cref="T:System.Windows.Forms.DataGridView"></see> wants to process the <see cref="T:System.Windows.Forms.Keys"></see> in keyData; otherwise, false.</param>
        public bool EditingControlWantsInputKey(Keys keyData, bool dataGridViewWantsInputKey)
        {
            return true;
        }

        ///<summary>
        ///Retrieves the formatted value of the cell.
        ///</summary>
        ///
        ///<returns>
        ///An <see cref="T:System.Object"></see> that represents the formatted version of the cell contents.
        ///</returns>
        ///
        ///<param name="context">A bitwise combination of <see cref="T:System.Windows.Forms.DataGridViewDataErrorContexts"></see> values that specifies the context in which the data is needed.</param>
        public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
        {
            if (mv.MonthViewControl.IsNull)
            {
                return string.Empty;
            }

            return SelectedDateTime.ToString("G");
        }

        ///<summary>
        ///Prepares the currently selected cell for editing.
        ///</summary>
        ///
        ///<param name="selectAll">true to select all of the cell's content; otherwise, false.</param>
        public void PrepareEditingControlForEdit(bool selectAll)
        {
            if (selectAll)
            {
                TextBox.SelectAll();
            }
            else
            {
                TextBox.SelectionStart = TextBox.Text.Length;
            }
        }

        ///<summary>
        ///Gets or sets the <see cref="T:System.Windows.Forms.DataGridView"></see> that contains the cell.
        ///</summary>
        ///
        ///<returns>
        ///The <see cref="T:System.Windows.Forms.DataGridView"></see> that contains the <see cref="T:System.Windows.Forms.DataGridViewCell"></see> that is being edited; null if there is no associated <see cref="T:System.Windows.Forms.DataGridView"></see>.
        ///</returns>
        public DataGridView EditingControlDataGridView
        {
            get { return editingControlDataGridView; }
            set { editingControlDataGridView = value; }
        }

        ///<summary>
        ///Gets or sets the formatted value of the cell being modified by the editor.
        ///</summary>
        ///
        ///<returns>
        ///An <see cref="T:System.Object"></see> that represents the formatted value of the cell.
        ///</returns>
        ///
        public object EditingControlFormattedValue
        {
            get { return SelectedDateTime; }
            set { SelectedDateTime = (DateTime) value; }
        }

        ///<summary>
        ///Gets or sets the index of the hosting cell's parent row.
        ///</summary>
        ///
        ///<returns>
        ///The index of the row that contains the cell, or �1 if there is no parent row.
        ///</returns>
        ///
        public int EditingControlRowIndex
        {
            get { return editingControlRowIndex; }
            set { editingControlRowIndex = value; }
        }

        ///<summary>
        ///Gets the cursor used when the mouse pointer is over the <see cref="P:System.Windows.Forms.DataGridView.EditingPanel"></see> but not over the editing control.
        ///</summary>
        ///
        ///<returns>
        ///A <see cref="T:System.Windows.Forms.Cursor"></see> that represents the mouse pointer used for the editing panel. 
        ///</returns>
        ///
        public Cursor EditingPanelCursor
        {
            get { return Cursors.Default; }
        }

        ///<summary>
        ///Gets or sets a value indicating whether the cell contents need to be repositioned whenever the value changes.
        ///</summary>
        ///
        ///<returns>
        ///true if the contents need to be repositioned; otherwise, false.
        ///</returns>
        ///
        public bool RepositionEditingControlOnValueChange
        {
            get { return true; }
        }

        /// <summary>
        /// Small utility function that updates the local dirty state and 
        /// notifies the grid of the value change.
        /// </summary>
        private void NotifyDataGridViewOfValueChange()
        {
            if (EditingControlValueChanged)
                EditingControlDataGridView.NotifyCurrentCellDirty(true);
        }

        /// <summary>
        /// Property which indicates whether the value of the editing control has changed or not
        /// </summary>
        public virtual bool EditingControlValueChanged
        {
            get { return valueChanged; }
            set { valueChanged = value; }
        }
    }

    #endregion

    #region DataGridViewFADateTimePickerColumn

    [ToolboxBitmap(typeof (DataGridViewFADateTimePickerColumn), "DataGridViewFADateTimePickerColumn.bmp")]
    public class DataGridViewFADateTimePickerColumn : DataGridViewColumn
    {
        #region Ctor

        public DataGridViewFADateTimePickerColumn() : base(new DataGridViewFADateTimePickerCell())
        {
        }

        #endregion

        #region Props

        public ThemeTypes Theme
        {
            get { return FADatePickerCellTemplate.Theme; }
            set { FADatePickerCellTemplate.Theme = value; }
        }

        [DefaultValue("Center")]
        public StringAlignment VerticalAlignment
        {
            get { return FADatePickerCellTemplate.VerticalAlignment; }
            set { FADatePickerCellTemplate.VerticalAlignment = value; }
        }

        [DefaultValue("Near")]
        public StringAlignment HorizontalAlignment
        {
            get { return FADatePickerCellTemplate.HorizontalAlignment; }
            set { FADatePickerCellTemplate.HorizontalAlignment = value; }
        }

        /// <summary>
        /// Represents the implicit cell that gets cloned when adding rows to the grid.
        /// </summary>
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override DataGridViewCell CellTemplate
        {
            get { return base.CellTemplate; }
            set
            {
                DataGridViewFADateTimePickerCell dataGridViewFADateTimePickerCell = value as DataGridViewFADateTimePickerCell;
                if (value != null && dataGridViewFADateTimePickerCell == null)
                    throw new InvalidCastException("Value provided for CellTemplate must be of type DataGridViewRadioButtonElements.DataGridViewRadioButtonCell or derive from it.");

                base.CellTemplate = value;
            }
        }

        /// <summary>
        /// Small utility function that returns the template cell as a DataGridViewRadioButtonCell.
        /// </summary>
        private DataGridViewFADateTimePickerCell FADatePickerCellTemplate
        {
            get { return (DataGridViewFADateTimePickerCell) CellTemplate; }
        }

        /// <summary>
        /// Replicates the MaxDisplayedItems property of the DataGridViewRadioButtonCell cell type.
        /// </summary>
        [Category("Behavior")]
        [Description("The maximum number of radio buttons to display in the cells of the column.")]
        public DateTime SelectedDateTime
        {
            get
            {
                if (FADatePickerCellTemplate == null)
                    throw new InvalidOperationException("Operation cannot be completed because this DataGridViewColumn does not have a CellTemplate.");

                return FADatePickerCellTemplate.SelectedDateTime;
            }
            set
            {
                if (SelectedDateTime != value)
                {
                    FADatePickerCellTemplate.SelectedDateTime = value;
                    if (DataGridView != null)
                    {
                        DataGridViewRowCollection dataGridViewRows = DataGridView.Rows;
                        int rowCount = dataGridViewRows.Count;

                        for (int rowIndex = 0; rowIndex < rowCount; rowIndex++)
                        {
                            DataGridViewRow dataGridViewRow = dataGridViewRows.SharedRow(rowIndex);
                            DataGridViewFADateTimePickerCell dataGridViewCell = dataGridViewRow.Cells[Index] as DataGridViewFADateTimePickerCell;

                            if (dataGridViewCell != null)
                                dataGridViewCell.SelectedDateTime = value;
                        }

                        DataGridView.InvalidateColumn(Index);
                        // TODO: Add code to autosize the column and rows, the column headers,
                        // the row headers, depending on the autosize settings of the grid.
                    }
                }
            }
        }
        
        

        #endregion

        #region Overrides

        /// <summary>
        /// Returns a standard compact string representation of the column.
        /// </summary>
        public override string ToString()
        {
            StringBuilder sb = new StringBuilder(64);
            sb.Append("DataGridViewFADateTimePickerCell { Name=");
            sb.Append(Name);
            sb.Append(", Index=");
            sb.Append(Index.ToString(CultureInfo.CurrentCulture));
            sb.Append(" }");
            return sb.ToString();
        }

        #endregion
    }

    #endregion
}

I want to make it possible to add FADatePicker to RadGridView but I don't know how.

Please guide me.
thank you.
Stefan
Telerik team
 answered on 25 Oct 2010
2 answers
107 views
hi,

Overlap of Controls in English and Korean OS.

the form attached is developed in korean os ,In korean PC it looks good.

But in English OS pc it ovelaps.

Please find the attached files
Stefan
Telerik team
 answered on 25 Oct 2010
3 answers
175 views
Hi Emanuel, Are you working on my FADatePicker? If yes, let me know.
Emanuel Varga
Top achievements
Rank 1
 answered on 25 Oct 2010
5 answers
746 views
I want to set the border color of a cell element to red based on a condition in row formatting  event, but even when I set BorderColor = Color.Red, it does not work. Even setting border thickness of cell element does not work.
How would I do this in cell formatting event?
I am using Q1 2008 SP1 version. the code that I am using and it does not set border is as below.

Thanks
Sunil
if (e.RowElement != null && e.RowElement.RowInfo is GridViewDataRowInfo)
           {
               GridCellElement cellElement = e.RowElement.RowInfo.Cells["AttributeName"].CellElement;
               if (cellElement!=null && (int)e.RowElement.RowInfo.Cells["AttributeId"].Value == _duplicateRowIndex)
               {
                   cellElement.ForeColor= Color.Red;
                   cellElement.ToolTipText = "You input duplicate Attribute Name";
                   cellElement.BorderThickness = new Padding(1, 1, 1, 1);
                   cellElement.BorderColor = Color.Red;
                   cellElement.DrawBorder = true;
               }
               else
               {
                   cellElement.ResetValue(VisualElement.ForeColorProperty);
                   cellElement.ToolTipText = string.Empty;
                   cellElement.ResetValue(LightVisualElement.BorderColorProperty);
               }
           }
SUNIL
Top achievements
Rank 3
Iron
Iron
Iron
 answered on 24 Oct 2010
1 answer
70 views
I wrote my own code for handling resizing so that I could get the resizing functionality that I want. It all works fine ... until I display a scroll bar. Then the size is too large.

I thought "easy enough", I will just add a check for a scroll bar and make my widths shorter. From reading, it sounded like I should use VScroll to check that. However, this value is *always* false, even when the scroll bar is showing.

Is there a way my code can know that the scroll bar is showing so I can resize my columns appropriately?

Thanks!
Deborah
Top achievements
Rank 1
 answered on 23 Oct 2010
Narrow your results
Selected tags
Tags
GridView
General Discussions
Scheduler and Reminder
Treeview
Dock
RibbonBar
Themes and Visual Style Builder
ChartView
Calendar, DateTimePicker, TimePicker and Clock
DropDownList
Buttons, RadioButton, CheckBox, etc
ListView
ComboBox and ListBox (obsolete as of Q2 2010)
Chart (obsolete as of Q1 2013)
Form
PageView
MultiColumn ComboBox
TextBox
RichTextEditor
PropertyGrid
Menu
RichTextBox (obsolete as of Q3 2014 SP1)
Panelbar (obsolete as of Q2 2010)
PivotGrid and PivotFieldList
Tabstrip (obsolete as of Q2 2010)
MaskedEditBox
CommandBar
PdfViewer and PdfViewerNavigator
ListControl
Carousel
Diagram, DiagramRibbonBar, DiagramToolBox
GanttView
Panorama
New Product Suggestions
Toolstrip (obsolete as of Q3 2010)
VirtualGrid
AutoCompleteBox
Label
Spreadsheet
ContextMenu
Panel
Visual Studio Extensions
TitleBar
Documentation
SplitContainer
Map
DesktopAlert
ProgressBar
CheckedDropDownList
TrackBar
MessageBox
Rotator
SpinEditor
StatusStrip
CheckedListBox
LayoutControl
SyntaxEditor
Wizard
ShapedForm
TextBoxControl
Conversational UI, Chat
DateTimePicker
CollapsiblePanel
TabbedForm
CAB Enabling Kit
GroupBox
DataEntry
ScrollablePanel
ScrollBar
WaitingBar
ImageEditor
Tools - VSB, Control Spy, Shape Editor
BrowseEditor
DataFilter
ColorDialog
FileDialogs
Gauges (RadialGauge, LinearGauge, BulletGraph)
ApplicationMenu
RangeSelector
CardView
WebCam
BindingNavigator
PopupEditor
RibbonForm
Styling
TaskBoard
Barcode
Callout
ColorBox
PictureBox
FilterView
Accessibility
VirtualKeyboard
NavigationView
DataLayout
ToastNotificationManager
ValidationProvider
CalculatorDropDown
Localization
TimePicker
ButtonTextBox
FontDropDownList
Licensing
BarcodeView
BreadCrumb
Security
LocalizationProvider
Dictionary
Overlay
Flyout
Separator
SparkLine
TreeMap
StepProgressBar
SplashScreen
ToolbarForm
NotifyIcon
DateOnlyPicker
Rating
TimeSpanPicker
Calculator
OfficeNavigationBar
TaskbarButton
HeatMap
SlideView
PipsPager
AIPrompt
TaskDialog
TimeOnlyPicker
+? more
Top users last month
Will
Top achievements
Rank 2
Iron
Motti
Top achievements
Rank 1
Iron
Hester
Top achievements
Rank 1
Iron
Bob
Top achievements
Rank 3
Iron
Iron
Veteran
Thomas
Top achievements
Rank 2
Iron
Want to show your ninja superpower to fellow developers?
Top users last month
Will
Top achievements
Rank 2
Iron
Motti
Top achievements
Rank 1
Iron
Hester
Top achievements
Rank 1
Iron
Bob
Top achievements
Rank 3
Iron
Iron
Veteran
Thomas
Top achievements
Rank 2
Iron
Want to show your ninja superpower to fellow developers?
Want to show your ninja superpower to fellow developers?