none
New to C# and need some help and guidance RRS feed

  • Question

  • Hi everyone.  I'm new to C# and I'm trying to figure out if the code below will work for the GetControlName routine and how I would go about coding the GetValueFromId routine.  This will be using the entity framework.  Any help and assistance would be appreciated.  Thanks.

            public IEnumerable<Control> Controls { get; private set; }
            public override string GetControlName(string FieldName)
            {
                foreach(Control c in this.Controls)
                    if (c.Name == FieldName)
                    return c.Name;
                return null;
               
            }
            public override string GetValueFromId(string ControlName, Guid? IdField)
            {
                throw new NotImplementedException("GetValueFromId");
            }


    • Edited by mrbill65 Wednesday, October 10, 2018 1:22 PM
    Wednesday, October 10, 2018 1:21 PM

All replies

  • The method would work, but it doesn't really do anything interesting either.  It is a fancy way of telling you if a control exists with that name, since the method will return string or null.  Was that the intent?

    Wednesday, October 10, 2018 1:59 PM
  • Well, I think what is expected is to get the controls name based on an entity's field name.  For instance, using the field name of Account, grab the controls name where the field is being placed/held such as a textbox, txtAccount or combox, cboAccount, etc.  I thought it was a bit much, would something like this work as well?

    if (FieldName != null)

        {

            return FieldName;

        }

    else

         {

            return null;

         {

    • Edited by mrbill65 Wednesday, October 10, 2018 2:28 PM
    Wednesday, October 10, 2018 2:25 PM
  • So given a set of controls you're trying to find the (first) one that has a name set to a particular field name? I would argue that you don't really need to do all this. 

    1) It looks like you're wrapping a set of controls and overriding some methods in some base type. Do you really need this inheritance at all? You can do this same thing with a simple LINQ query against any IEnumerable<Control>. You don't need a type to wrap it. You could even create an extension method that does the same thing.

    //Untested
    public static class ControlExtensions
    {
       public static Control GetControlByName ( this IEnumerable<Control> source, string name )
       {
          return source.FirstOrDefault(c => c.Name == name);
       }
    }
    

    Note here I'm returning the control, not the name. In your method you're returning the name but you already have that so this is really checking for the existence of a control in my opinion. So I'd change it to an Exists method instead.

    //In class from earlier
    public static bool Exists ( IEnumerable<Control> source, string name )
    {
       return GetControlByName(source, name) != null;
    }
    

    2) If you're ultimately working with Winforms controls then you have a ControlCollection class under the hood. This class already has a Find method that takes a field name and returns the corresponding control so you don't really need any of this. It also handles the case of nested controls.


    Michael Taylor http://www.michaeltaylorp3.net

    Wednesday, October 10, 2018 2:30 PM
    Moderator
  • Would this bring me back the controls name like txtAccount or cboAccount or something else?

                        s = Controls.FirstOrDefault(c => c.Name == FieldName).ToString();

    Wednesday, October 10, 2018 9:26 PM
  • The code you post wouldn't. The FirstOrDefault would get you the first control that matches the condition. It would then call ToString on the instance that came back. In the case of it finding a control then calling ToString() would return the type name in most cases. If it didn't find anything then you'd get a null reference exception. So either you'll get a typename or an exception.

    //Gets the control and then calls ToString which normally just returns the type
    var control = Controls.FirstOrDefault(c => c.Name == "NameOfAControl").ToString();
    
    
    //Will crash because FirstOrDefault returns null then you try to use it and it crashes
    var control2 = Controls.FirstOrDefault(c => c.Name == "DoesNotExist").ToString();
    
    //This would return either the ToString result (type name most likely) or an empty string because you're handling null
    var control3 = Controls.FirstOrDefault(c => c.Name == "MayOrMayNotExist")?.ToString() ?? "";

    If you want the name of the control then that is what the Name property is for. But if you're using FirstOrDefault to find a control by its name then if you get a non-null value back then you already have the name because that is what you queried for. 

    Are you dynamically generating these controls? If so then FieldName would need to line up with the Name property of one of the controls you dynamically created. If it didn't then you wouldn't match.

    //In your form init code or wherever you're creating your UI
    foreach (var field in someListOfFields)
    {
       var control = new TextBox();
       control.Name = field;
       …;
    }
    
    //Later in your code
    foreach (var field in someListOfFields)
    {
       //This would work since you used the same list of fields
       //to create the controls and you ensure the name of the control matched the name of the field
       var control = Controls.FirstOrDefault(c => c.Name == field);
    };
    
    //This would return nothing unless 'DoesNotExist' was actually a field name
    var willBeNull = Controls.FirstOrDefault(c => c.Name == "DoesNotExist");
    

    But if you're not dynamically creating these controls (e.g. you're creating the controls in the designer) then there is already a field to back the control so you probably don't need to be searching for the control by name, just use the field name that is auto-generated by the designer.

    Also, ControlCollection already contains a Find method so I'd recommend you just use it instead of FirstOrDefault or a foreach loop. It will return back the Control, if it finds it or null otherwise. It behaves like FirstOrDefault in this case. 



    Michael Taylor http://www.michaeltaylorp3.net

    Thursday, October 11, 2018 2:24 AM
    Moderator