0

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

我想编写一种方法,可以通过将 int 值传递给他的一个属性来访问用户控件。

例如:如果方法签名是: void SetMeasuredValueToProbe(int probe_number, int value ) 然后传递 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;                       
        }             
    }

我想知道这样做的优雅方式,而无需制作意大利面条代码。

4

1 回答 1

0

一种方法可能是给x:NameGrid

<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 树中,一切都应该正常工作。

我希望这有帮助。

于 2019-10-11T15:46:38.497 回答