В настоящее время я работаю над приложением, в котором информация ищется, а затем извлекается из документа 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.