在 C# wpf 中如何遍历网格并获取网格内的所有标签

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22794445/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 11:25:28  来源:igfitidea点击:

in C# wpf how to loop through a grid and get all the labels inside of the grid

c#wpf

提问by Doctor06

So you know how in c# using normal forms you can loop through a panel and get all the labels inside of it? So you can do something like this:

那么您知道如何在 c# 中使用标准表单循环遍历面板并获取其中的所有标签吗?所以你可以做这样的事情:

foreach(Label label in Panel.Controls)

is there a way of doing this for grids? something like

有没有办法为网格做到这一点?就像是

foreach(Lable lable in Grid)

so this foreach could be inside a function that passes a grid object like so

所以这个 foreach 可能在一个传递网格对象的函数中

private void getLabels(Grid myGrid)
{
  foreach(Label label in myGrid)
}

if i do this, it tells me "error CS1579: foreach statement cannot operate on variables of type 'System.Windows.Controls.Grid' because 'System.Windows.Controls.Grid' does not contain a public definition for 'GetEnumerator'"

如果我这样做,它会告诉我“错误 CS1579:foreach 语句不能对类型为‘System.Windows.Controls.Grid’的变量进行操作,因为‘System.Windows.Controls.Grid’不包含‘GetEnumerator’的公共定义”

is there another way of doing this that i am now aware of?

我现在知道还有另一种方法吗?

Any help would be appreciated.

任何帮助,将不胜感激。

采纳答案by djdanlib

Iterate through Grid.Children and cast everything to Label. If it's not null, you have found a Label.

遍历 Grid.Children 并将所有内容转换为 Label。如果它不为空,你就找到了一个标签。

回答by Federico Berasategui

normal forms- WPF us the normalway of doing .Net Windows UIs in 2014.

normal forms- WPF 我们在 2014 年做 .Net Windows UI的正常方式。

If you're working with WPF, you need to leave behind any and all notions you got from ancient technologies and understand and embrace The WPF Mentality.

如果您正在使用 WPF,则需要抛开从古老技术中获得的任何和所有概念,并理解并接受WPF 心态

Basically, you don't "iterate" over anything in WPF because there's absolutely no need to do so.

基本上,您不会“迭代”WPF 中的任何内容,因为绝对没有必要这样做。

The UI's responsibility is to showdata, not to storeit nor manipulateit. Therefore whatever data you need to show must be stored in a proper Data Model or ViewModeland the UI must use proper DataBindingto access that, rather than procedural code.

UI 的职责是显示数据,而不是存储操作数据。因此,您需要显示的任何数据都必须存储在适当的数据模型或视图模型中,并且 UI 必须使用适当的数据绑定来访问它,而不是过程代码。

So, for example, say you have a Personclass:

因此,例如,假设您有一个Person类:

public class Person
{
    public string LastName {get;set;}

    public string FirstName {get;set;}
}

You will want to set the UI's DataContextto a list of that:

您需要将 UI 的DataContext设置为以下列表:

//Window constructor:
public MainWindow()
{
    //This is required.
    InitializeComponent();

    //Create a list of person
    var list = new List<Person>();

    //... Populate the list with data.

    //Here you set the DataContext.
    this.DataContext = list;
}

Then you will want to show that in a ListBoxor another ItemsControl-based UI:

然后你会想要在一个ListBox或另一个ItemsControl基于 UI 中显示它:

<Window ...>
    <ListBox ItemsSource="{Binding}">

    </ListBox>
</Window>

And then you'll want to use WPF's Data Templatingcapabilities to define how to show each instance of the Personclass in the UI:

然后您需要使用 WPF 的数据模板功能来定义如何Person在 UI 中显示类的每个实例:

<Window ...>
   <Window.Resources>
      <DataTemplate x:Key="PersonTemplate">
          <StackPanel>
              <TextBlock Text="{Binding FirstName}"/>
              <TextBlock Text="{Binding LastName"/>
          </StackPanel>
      </DataTemplate>
   </Window.Resources>

   <ListBox ItemsSource="{Binding}"
            ItemTemplate="{StaticResource PersonTemplate}"/>
</Window>

Finally, if you need to change the Dataat runtime, and have those changes reflected (shown) in the UI, your DataContext classes must Implement INotifyPropertyChanged:

最后,如果您需要在运行时更改数据,并在 UI 中反映(显示)这些更改,您的 DataContext 类必须实现INotifyPropertyChanged

public class Person: INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string name)
    {
        var handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(name));
    }

    private string _lastName;
    public string LastName
    {
        get { return _lastName; }
        set
        {
            _lastName = value;
            OnPropertyChanged("LastName");
        }
    }

    private string _firstName;
    public string FirstName
    {
        get { return _firstName; }
        set
        {
            _firstName = value;
            OnPropertyChanged("FirstName");
        }
    }
}

Finally you iterate over the List<Person>and change the data items' properties rather than manipulating the UI:

最后,您迭代List<Person>并更改数据项的属性,而不是操作 UI:

foreach (var person in list)
    person.LastName = "Something";

While leaving the UI alone.

单独留下用户界面。