-1

I want to iterate thorough a specific Row in a Grid of Wpf and get the UI Element inside each cell of this Row. i have searched a lot but haven't found any solution for this ! The UI element is of Type TextBlock.

Explanation
As you can see in attached image. I have a Grid that has some Rows and Columns. I want to iterate through Row 0 and compare the TextBlock.Text inside each cell of Row 0 with some text. How to do that ?

Image here

Hammas_Stack1
  • 184
  • 1
  • 13
  • What do you want to do with the UI Elements while iterating? – Daniel W. Jan 03 '19 at 08:00
  • @DanielW. as the Ui element is `TextBlock`. i want to get `TextBlock.Text` property of it ! – Hammas_Stack1 Jan 03 '19 at 08:03
  • It doesn’t sound like a hard job to do. Do you have trouble in casting the object to UIElement? – kennyzx Jan 03 '19 at 08:04
  • @kennyzx honestly i tried a lot but it;s kinda hard job for me now . Casting is not an issue .. idk how to iterate through a specific row and each cell of it ! – Hammas_Stack1 Jan 03 '19 at 08:05
  • 1
    If you just want to have the text, why not use a binding and iterate througt the values in the bound Objects/List? – Daniel W. Jan 03 '19 at 08:05
  • @DanielW. what i'm trying to do is . get each cell Ui element Text property and compare it with some text and then if the compare is Succeful get the COLUMN index of that particular Ui Element that matched :( – Hammas_Stack1 Jan 03 '19 at 08:08
  • Check [this question](https://stackoverflow.com/questions/15686381/wpf-iterate-through-datagrid). HTH. The accepted answer seems to be “over complicated”, check the one below. – kennyzx Jan 03 '19 at 08:14
  • @kennyzx nope ! no 1 it's for `DataGrid` and i'm talking about just `Grid`. and solutions there doesnt seem to be working for me . – Hammas_Stack1 Jan 03 '19 at 08:19
  • How to you create the TextBlocks in the Grid? Are they bound? – Daniel W. Jan 03 '19 at 08:22
  • they are hard coded in `Xaml` ! like this `BAY` – Hammas_Stack1 Jan 03 '19 at 08:23
  • Sorry this seams to be a really bad style, why not use DataGrid, it is really flexibel even to change the design and you would be able to do things in the View and not in the View? – Daniel W. Jan 03 '19 at 08:38

2 Answers2

0

First you can get Grid’s Children collection, then you can check for each element which row it is positioned:

foreach (var element in grid1.Children) {
    if (grid1.GetRow(element) == 0) {
        //now you get all the UIElements in the first row
    }
}
kennyzx
  • 12,845
  • 6
  • 39
  • 83
0

For holding View and ViewModel devided and not use CodeBehind for logic I would recommend to use a DataGrid and Binding to search for, so View would be like:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="30"></RowDefinition>
        <RowDefinition Height="*"></RowDefinition>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"></ColumnDefinition>
        <ColumnDefinition Width="*"></ColumnDefinition>
    </Grid.ColumnDefinitions>

    <TextBox Text="{Binding SearchText, UpdateSourceTrigger=PropertyChanged}" Grid.Row="0" Grid.Column="0"></TextBox>
    <TextBlock Text="{Binding SearchResult}" Grid.Row="0" Grid.Column="1"></TextBlock>

    <DataGrid ItemsSource="{Binding Entries}" Grid.Row="1" Grid.ColumnSpan="2">
    </DataGrid>
</Grid>

So SearchText is what to search for and SearchResult is the result. Both are bound to the ViewModel. And Connected View Model contains DoSearchBay() for update the SearchResult field with the value of the current SearchText, code be like:

public class ViewModel: INotifyPropertyChanged
{
    private String _searchText = "Bay?";
    private String _searchResult = "N/A";

    public ObservableCollection<MyDataObject> Entries { get; set; }

    public string SearchText
    {
        get => _searchText;
        set
        {
            if (value == _searchText) return;
            _searchText = value;
            DoSearchBay();
            OnPropertyChanged();
        }
    }

    private void DoSearchBay()
    {
        var sel = Entries.Select((dm, index) => new { index, dm.Bay}).FirstOrDefault(obj => obj.Bay.Equals(_searchText, StringComparison.OrdinalIgnoreCase)) ;
        if (sel != null)
        {
            SearchResult = "Found in row " + sel.index;
        }
        else
        {
            SearchResult = "N/A";
        }
    }

    public string SearchResult
    {
        get => _searchResult;
        set
        {
            if (value == _searchResult) return;
            _searchResult = value;
            OnPropertyChanged();
        }
    }


    public ViewModel()
    {
        //Create Fake values
        Entries = new ObservableCollection<MyDataObject>();
        Entries.Add(new MyDataObject() {Bay = "Bay1", Am9 = "value1-1", Am10 = "value1-2", Am11 = "value1-3" });
        Entries.Add(new MyDataObject() { Bay = "Bay2", Am9 = "value2-1", Am10 = "value2-2", Am11 = "value2-3" });
        Entries.Add(new MyDataObject() { Bay = "Bay3", Am9 = "value3-1", Am10 = "value1-2", Am11 = "value3-3" });
    }

    // ToDo Implement INotifyPropertyChanged...
}

The Model containing data my look like:

public class MyDataObject
{
    public String Bay { get; set; }
    public String Am9 { get; set; }
    public String Am10 { get; set; }
    public String Am11 { get; set; }
}
Daniel W.
  • 938
  • 8
  • 21