Как связать информацию с DataGrid в приложении WPF с несколькими windows? - PullRequest
2 голосов
/ 01 февраля 2020

В настоящее время я работаю над приложением, в котором информация ищется, а затем извлекается из документа Excel. Главное окно приложения - это окно, в котором пользователь ищет определенный элемент, и как только пользователь нажимает кнопку поиска, появляется другое окно, отображающее результаты этого поиска в DataGrid, однако моя DataGrid не может отобразить результаты поиск по DataGrid. На данный момент вся логика c, используемая для поиска и извлечения информации, происходит в кодовой части экрана поиска в главном окне, и я попытался связать информацию с сеткой данных следующим образом.

public partial class MainWindow : Window, INotifyPropertyChanged
{
     //Initialized variables for Result and Add New Cable windows
     private AddWindow newCableWindow;
     private ResultsWindow searchResults = new ResultsWindow();


    //Creates a list to hold all CableLines in ExcelDocument
    private BindingList<CableLine> cableLines = new BindingList<CableLine>();

     public BindingList<CableLine> CableLines
     {
            get { return cableLines; }
            set
            {
                if (!cableLines.Equals(value))
                {
                    cableLines = value;
                    RaisePropertyChanged("CableLines");
                }
            }
     }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void RaisePropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    private void SearchButton_Click(object sender, RoutedEventArgs e)
    {

        SearchExcel(SearchType.CableSize);

        searchResults.Show();

    }
}

в главном окне кода. Однако это не windows, который будет отображать информацию, собранную при нажатии кнопки поиска. Итак, в классе результатов я попробовал это.

public partial class ResultsWindow : Window, INotifyPropertyChanged
{
    MainWindow searchWindow;
    AddWindow newCableWindow;

    private BindingList<CableLine> cableLines = new BindingList<CableLine>();

    public BindingList<CableLine> CableLines
    {
        get { return cableLines; }
        set
        {
            if (!cableLines.Equals(value))
            {
                CableLines = value;
                RaisePropertyChanged("CableLines");
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void RaisePropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

и в коде XAML для этого класса ResultsWindow я настроил DataGrid следующим образом:

<DataGrid
                Grid.Row="0"
                Height="225"
                AutoGenerateColumns="False"
                HorizontalAlignment="Center"
                Background="LightGray"
                ItemsSource="{Binding CableLines}"
                >


                <DataGrid.Columns>
                    <DataGridTextColumn Header="Job #" Width="Auto" Binding="{Binding JobNo}"/>
                    <DataGridTextColumn Header="Page #" Width="Auto" Binding="{Binding PageNo}"/>
                    <DataGridTextColumn Header="Link To Job" Width="Auto" Binding="{Binding LinkToJob}"/>
                    <DataGridTextColumn Header="PCU Part #" Width="Auto" Binding="{Binding PCUPartNo}"/>
                    <DataGridTextColumn Header="Manufacturing Part #" Width="Auto" Binding="{Binding ManufactPartNo}"/>
                    <DataGridTextColumn Header="Manufacturer" Width="Auto" Binding="{Binding Manufacturer}"/>
                    <DataGridTextColumn Header="Cable Conductor Size" Width="Auto" Binding="{Binding CableConductorSize}"/>
                    <DataGridTextColumn Header="Description" Width="Auto" Binding="{Binding Description}"/>
                    <DataGridTextColumn Header="QTY" Width="Auto" Binding="{Binding QTY}"/>
                    <DataGridTextColumn Header="Group Number" Width="Auto" Binding="{Binding GroupNum}"/>
                </DataGrid.Columns>
            </DataGrid>

У меня есть ощущение, что проблема возникает из-за того, что поиск выполняется в коде MainWindow и, следовательно, в списке ItemSource для DataGrid, который обновляется с помощью функции внутри функции SearchButton_Click и не обновляется в коде для Result Окно, я просто не уверен, как мне это сделать или как лучше подойти к этому. Это действительно первое приложение, над которым я когда-либо работал, и я новичок в концепции WPF и использую несколько windows в приложении, и я знаю, что это много информации, поэтому я ценю любую помощь, которую могу получить. Заранее спасибо.

ОБНОВЛЕНИЕ: Элементы добавляются в кабельную линию через функцию SearchExcel, которая выполняется в обработчике события SearchButton_Click. Функция выглядит следующим образом:

private void SearchExcel (SearchType searchType) {

        var searchedRows = new List<int>();

        //Switch statement making a decision based on how the user searched for the cable
        switch (searchType)
        {
            case SearchType.CableSize:
                int cableSizeColumn = GetColumnNum("Cable Conductor Size");

                //Checks that the correct column in the spreadsheet was found.
                if (cableSizeColumn == -1)
                {
                    throw new InvalidOperationException("The \"Cable Conductor Size\" could not be found.");
                }

                //variable to keep track of the last row that contained a value since only first cell in merged cells contains the value
                int lastGoodRow = 0;

                //Searches through every row in the column, getting the rows where the size number matches the search
                for (int i = HeaderRow + 1; i <= usedRows.Count(); i++)
                {
                    var currentCellValue = Convert.ToString(cableSheet.Cells[i, cableSizeColumn].Value2);
                    var desiredCellValue = Convert.ToString(CableSizeDropdown.Text);

                    if (String.Equals(desiredCellValue, currentCellValue))
                    {
                        lastGoodRow = i;
                        searchedRows.Add(i);
                    }
                    else if(currentCellValue == null && !IsRowEmpty(i))
                    {
                        searchedRows.Add(++lastGoodRow);
                    }
                }
                break;

                //TODO: Add switch statement for other kind of search
        }

        //Ensures that rows have been found that correspond correctly to the search
        if(searchedRows.Count == 0)
        {
            throw new InvalidOperationException($"The chosen cable size {CableSizeDropdown.Text.ToString()} could not be found.");
        }

        foreach (int row in searchedRows)
        {
            AddLine(row);
        }
    }

, где сначала сохраняются номера строк с нужной информацией (на листе Excel строки с одинаковыми информация в столбце, который я ищу, объединена, что означает, что только первая ячейка фактически содержит значение, которое я ищу, поэтому я добавляю проверку на ноль и проверяю, что строка не пуста, так как если это конкретное значение строки равно нулю, но сама строка не пуста, это означает, что строка также содержит искомое значение). После того, как у меня есть номера строк, которые имеют значение, которое я ищу, я вызываю метод AddLine для каждого номера строки, в котором вещи фактически добавляются в список CableLines.

       private void AddLine(int rowNum)
    {
        string pageNo = "";
        string jobNo = "";
        string linkToJob = "";
        string pcuPartNo = "";
        string manufactPartNo = "";
        string manufact = "";
        string description = "";
        int cableConductorSize = 0;
        int qty = 0;
        int groupNum = 0;

        //iterates through every cell in row number and gets the information from it
        for (int i = 1; i <= usedColumns.Count(); i++)
        {
            if (i == GetColumnNum("Job #"))
            {
                jobNo = (cableSheet.Cells[rowNum, i].Value2 != null) ? cableSheet.Cells[rowNum, i].Value2.ToString() : "";
                break;
            }
            else if (i == GetColumnNum("Page #"))
            {
                pageNo = (cableSheet.Cells[rowNum, i].Value2 != null) ? cableSheet.Cells[rowNum, i].Value2.ToString() : "";
                break;
            }
            else if (i == GetColumnNum("Link To Job"))
            {
                linkToJob = (cableSheet.Cells[rowNum, i].Value2 != null) ? cableSheet.Cells[rowNum, i].Value2.ToString() : "";
                break;
            }
            else if (i == GetColumnNum("PCU Part #"))
            {
                pcuPartNo = (cableSheet.Cells[rowNum, i].Value2 != null) ? cableSheet.Cells[rowNum, i].Value2.ToString() : "";
                break;
            }
            else if (i == GetColumnNum("Manufacturing Part #"))
            {
                manufactPartNo = (cableSheet.Cells[rowNum, i].Value2 != null) ? cableSheet.Cells[rowNum, i].Value2.ToString() : "";
                break;
            }
            else if (i == GetColumnNum("Manufacturer"))
            {
                manufact = (cableSheet.Cells[rowNum, i].Value2 != null) ? cableSheet.Cells[rowNum, i].Value2.ToString() : "";
                break;
            }
            else if (i == GetColumnNum("Cable Conductor Size"))
            {
                cableConductorSize = (cableSheet.Cells[rowNum, i].Value2 != null) ? cableSheet.Cells[rowNum, i].Value2.ToString() : "";
                break;
            }
            else if (i == GetColumnNum("Description"))
            {
                description = (cableSheet.Cells[rowNum, i].Value2 != null) ? cableSheet.Cells[rowNum, i].Value2.ToString() : "";
                break;
            }
            else if (i == GetColumnNum("QTY"))
            {
                qty = (cableSheet.Cells[rowNum, i].Value2 != null) ? Convert.ToInt32(cableSheet.Cells[rowNum, i].Value2) : 0;
                break;
            }
            else if (i == GetColumnNum("Group Number"))
            {
                groupNum = (cableSheet.Cells[rowNum, i].Value2 != null) ? Convert.ToInt32(cableSheet.Cells[rowNum, i].Value2) : 0;
                break;
            }
            else
            {
                throw new InvalidOperationException("An invalid column was recognized.");
            }
        }

        cableLines.Add(new CableLine(jobNo, pageNo, linkToJob, pcuPartNo, manufactPartNo, manufact, description, cableConductorSize, qty, groupNum));
    }

Мысль здесь является то, что функция получает номер строки и проходит через каждую используемую ячейку в этой строке и добавляет информацию к определенному свойству класса CableLine (который является просто классом для представления отдельной строки информации на листе Excel), и когда это делается , он добавляет новый объект CableLine в список CableLines вместе с информацией, собранной из строки в листе Excel.

1 Ответ

1 голос
/ 03 февраля 2020

Мне удалось самостоятельно найти решение проблемы, работая над проектом. Все, что мне нужно было сделать, это сослаться на DataGrid x: Name, используя экземпляр окна Results, а затем установить DataSrid ItemSource на список кабельных линий, обновляемый с помощью функции AddLine. Поэтому после каждого l oop в функции SearchExcel, где вызывается метод AddLine (), я просто ссылаюсь на searchResults.searchResults (в данном случае это x: Name, которое я дал моей DataGrid) .ItemSource = cableLines, и это работало нормально для меня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...