views:

351

answers:

2

In a WPF app I have objects, derived from a custom control:

...
<MyNamespace:MyCustControl x:Name="x4y3" />
<MyNamespace:MyCustControl x:Name="x4y4" />
... 

I can reference these objects, using names:

x4y4.IsSelected = true;

Also such function works well:

 public void StControls(MyCustControl sname)
    {
     ...          
        sname.IsSelected = true;
     ...
    }

....

 StControls(x4y3);

But I want to use a string in order to reference an object when calling this method. Like this (but this isn't working):

        MyCustControl sc = new MyCustControl();
        string strSc = "x1y10";
        sc.Name = strSc;

        StControls(sc); // nothing's happening

And this way even doesn't compile:

        MyCustControl sc = new MyCustControl();
        string strSc = "x1y10";
        sc = (MyCustControl) strSc; // Cannot convert type string to MyCustControl 

        StControls(sc); 

How can I use string variable to manipulate with object (i.e. cast it to object)?

+8  A: 

Use FindName:-

 MyCustControl sc = (MyCustControl)this.FindName("x1y10");

When you use x:Name in the XAML a field with the name specified is created in a partial class that matches the class in the code behind cs. This partial class is where the implementation of InitialiseComponent is found. During execution of this method the object with that name is found and assigned to the field, FindName is used to do this.

When you have a string contain such a name you can simply call FindName yourself and then cast the returned object to the custom control type.

AnthonyWJones
This code gives a run-time error: "Object reference not set to an instance of an object". And: "Use the NEW keyword to create an object instance". I tried to use NEW keyword - but it doesn't help. What it can be?
rem
@rem: You have a control named "x1y10" in the XAML?
AnthonyWJones
@rem: that error makes no sense on the example line. There is no object reference, apart from `this`, but improper use would result in a compile time error. Most likely the `sc` variable is set to `null` because the control is not found, and the exception occurs when you try to access that control later in the code.
Thorarin
I'm awfully sorry - it is my typo error with the name of the object. There was no such object in XAML indeed. Everything's working excellent. Thank you very much!
rem
+3  A: 

This is not actually casting. You need to find the object reference for the control by name, which can be done like this:

MyCustControl control = (MyCustControl)frameworkElement.FindName("x4y3");

Where frameworkElement is the containing Window (or any Panel like a Grid). From the code behind of a window, using this should work :)

See also this question if you plan on creating the controls dynamically instead, which your naming scheme seems to suggest to me. However, if this is the case, FindName is not really necessary at all. You would just store references to all the created controls in a two-dimensional array as you create them.

int[,] controls = new int[10, 10];

for (int x = 0; x < 10; x++)
{
    for (int y = 0; y < 10; y++)
    {
        // Create new control and initialize it by whatever means
        MyCustControl control = new MyCustControl();

        // Add new control to the container       
        Children.Add(control);

        // Store control reference in the array
        controls[x, y] = control;
    }
}

Then later, you can just access the control like this:

controls[4, 3].IsSelected = true;
Thorarin
Thank you Thorarin! Anthony's answer was a little earlier, so I accepted his one. Your code example will be of great help for me. Thanks once again! +1
rem