在XAML定义的标签上循环

6

我有一个具有多个标签的WPF应用程序。

<Label x:Name="label1" />
<Label x:Name="label2" />
<Label x:Name="label3" />
....

我不想逐个为每个标签赋值,例如:

label1.content= 1;
label2.content= 20;
label3.content= 30;
....

我希望能够更多地像这样做:

for(int i = 1; i<40 ;i++)
{
    label"i".content = i*10;
}

有没有办法做到这一点?

3
你能否创建一个标签数组,然后进行循环处理? - Sam
我在XAML中创建了我的标签,如下所示:<Label x:Name="label1" /> <Label x:Name="label2" /> - user2261524
代码后台是创建标签的选项吗? - Sam
WPF应用程序?还是只在一个窗口/控件上? - slugster
1
如果您必须在XAML中定义每个标签,那么为什么添加 Text=1Text=10等会很糟糕?对我来说,使用代码后台会比仅在XAML中设置更具有迷惑性。 - default
6个回答

8
如果你的标签都是命名一致的,可以这样做:
var numberOfLabels = 40;

for(int i = 1; i <= numberOfLabels; i++)
{
    var labelName = string.Format("label{0}", i);
    var label = (Label) this.FindName(labelName);
    label.Content = i * 10;
}

3
如果您使用绑定,那么很容易。您只需要在ViewModel中将标签内容保存在ObservableCollection<string>中。然后,您可以随心所欲地使用它们,在您的情况下是迭代。
编辑1:
此外,您的xaml应该类似于:
        <ItemsControl ItemsSource="{Binding MyLabelValues}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <sdk:Label Content="{Binding Mode=TwoWay}"></sdk:Label>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>

同意。那应该是正确的方式! - Sebastian Ðymel

2
使用这段代码
public static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
{
    if (depObj != null)
    {
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
        {
            DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
            if (child != null && child is T)
            {
                yield return (T)child;
            }

            foreach (T childOfChild in FindVisualChildren<T>(child))
            {
                yield return childOfChild;
            }
        }
    }
}

您可以按类型枚举所有控件。
foreach (Label lbl in FindVisualChildren<Label>(window))
{
    // do something with lbl here
}

1
你可以在窗体构造函数中将所有这些Label添加到List<Label>中。
这是一个繁琐的工作,但你只需要做一次。
List<Label> labels = new List<Label>();
labels.Add(label1);
// etc.

// loop
for (int i = 0; i < labels.Count; i++)
    labels[i].Text = i.ToString();

// alternative loop
foreach (Label label in labels)
    label.Text = "test";

1
这个怎么样?
List<Label> labelL = new List<Label>();

for(int i = 1; i<40 ;i++)
    labelL.Add(new Label{ Name = "label"+i, Content = i*10 });

最终结果将是这样的。
label1.Text = 10;
label2.Text = 20;
label3.Text = 20;
...
...

0

你可以使用绑定来实现!

XAML视图:

<ItemsControl ItemsSource="{Binding List}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Label Content="{Binding Value, Mode=TwoWay}"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

在代码后台的构造函数中:

DataContext = new ViewModelClass();

在ViewModelClass中:

class ViewModelClass : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(string name)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
        }

        private ObservableCollection<StringObject> _List = new ObservableCollection<StringObject>();
        public ObservableCollection<StringObject> List
        {
            get { return _List; }
            set
            {
                _List = value;
                NotifyPropertyChanged("List");
            }
        }

        public ViewModelClass()
        {
            List = new ObservableCollection<StringObject>
                {
                    new StringObject {Value = "your"},
                    new StringObject {Value = "list"},
                    new StringObject {Value = "of"},
                    new StringObject {Value = "string"}
                };
        }
    }

    public class StringObject
    {
        public string Value { get; set; }
    }

注意使用类型为string的集合时,它不起作用,您必须使用一个对象 => StringObject


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接