如何通过标识符(名称,Uid ...)访问用户控件?

时间:2019-09-20 15:40:27

标签: c# wpf-controls xname

我已经建立了许多用户控件实例(到目前为止有16个)。 它们的每个都有相似的属性。我给每个人起了个名字:  x:Name =“ probeX”(其中X是整数)。 这些控件中的每一个都代表一个电探针。

我想编写一种方法,该方法可以通过传递int值到其属性之一来访问用户控件。

例如: 如果方法签名为: void SetMeasuredValueToProbe(int probe_number,int值) 然后通过 SetMeasuredValueToProbe(3,22);

会将“ probe3”特定属性设置为值22。

我知道我可以在一个方法中使用长开关。 但是将来我想以指数方式增加探测的数量。 因此,我想知道命名和访问用户控件数组的正确方法是什么。

XAML:

    <StackPanel
        Grid.Column="0">
        <uc:ProbeTestControl x:Name="probe1" x:Uid="1" ProbeValue ="1"/>
        <uc:ProbeTestControl x:Name="probe2" ProbeValue ="2"/>
        <uc:ProbeTestControl x:Name="probe3" ProbeValue ="3"/>
        <uc:ProbeTestControl x:Name="probe4" ProbeValue ="4"/>
        <uc:ProbeTestControl x:Name="probe5" ProbeValue ="5"/>
        <uc:ProbeTestControl x:Name="probe6" ProbeValue ="6"/>
        <uc:ProbeTestControl x:Name="probe7" ProbeValue ="7"/>
        <uc:ProbeTestControl x:Name="probe8" ProbeValue ="8"/>
    </StackPanel>
    <StackPanel
        Grid.Column="1">
        <uc:ProbeTestControl x:Name="probe9" ProbeValue ="9"/>
        <uc:ProbeTestControl x:Name="probe10" ProbeValue ="10"/>
        <uc:ProbeTestControl x:Name="probe11" ProbeValue ="11"/>
        <uc:ProbeTestControl x:Name="probe12" ProbeValue ="12"/>
        <uc:ProbeTestControl x:Name="probe13" ProbeValue ="13"/>
        <uc:ProbeTestControl x:Name="probe14" ProbeValue ="14"/>
        <uc:ProbeTestControl x:Name="probe15" ProbeValue ="15"/>
        <uc:ProbeTestControl x:Name="probe16" ProbeValue ="16"/>
    </StackPanel>

MainWindow类中的方法:

    private void SetMeasuredValueToProbe(int probe_number, int value )
    {
        switch (probe_number)
        {
            case 1:
                probe1.MeasuredValueBox = value;
                break;
            case 2:
                probe2.MeasuredValueBox = value;
                break;
            default:
                break;                       
        }             
    }

我想知道这样做的优雅方法,而无需编写意大利面条代码。

1 个答案:

答案 0 :(得分:0)

一种方法可能是将x:Name赋予根Grid

<Grid x:Name="LayoutRoot">
    ...
</Grid>

然后在代码中,您可以按名称找到探针用户控件。像这样:

var probe = LayoutRoot.GetChildByName<ProbeTestControl>($"probe{probe_number}");

这是我使用的扩展方法:

public static T GetChildByName<T>(this FrameworkElement element, string name)
    where T : FrameworkElement
{
    if (element == null) return null;
    return (T)element.FindName(name) ?? element.GetChildrenOfType<T>().FirstOrDefault(c => c.Name == name);
}

public static IEnumerable<T> GetChildrenOfType<T>(this DependencyObject element)
    where T : DependencyObject
{
    return element.GetChildrenRecursive().OfType<T>();
}

private static IEnumerable<DependencyObject> GetChildrenRecursive(this DependencyObject element)
{
    if (element == null)
    {
        throw new ArgumentNullException(nameof(element));
    }

    for (var i = 0; i < VisualTreeHelper.GetChildrenCount(element); i++)
    {
        var child = VisualTreeHelper.GetChild(element, i);

        yield return child;

        foreach (var item in child.GetChildrenRecursive())
        {
            yield return item;
        }
    }
}

只要所有探针都存在于同一XAML树中,一切都应该起作用。

我希望这会有所帮助。