I have a loop where I read items from an excel sheet and write them to textboxes and comboboxes on a WPF page. This loop is executed on the loading of the page.
For some reason if I have a Messagebox prior to the loop, it works just fine. If I don't have the messagebox, the Textboxes don't get the data written to them, but the comboboxes do.
Any advice on how to remove the messagebox and still have the code work would be appreciated.
Only reason I can think of for this working with the messagebox, is that the program is needing a delay for some reason, but I can't figure out why.
update:
I've figured out that it has something to do with my binding. When i removed that the field worked just fine, but i want this along with other fields to do calculations and updates when values are changed.
Quantity1 in the binding is a Private String in a class that gets called when the property changes.
xaml
<TextBox Grid.Column="1" Grid.Row="2" Width="60" Name="Quantity1" TextAlignment="Center" FontFamily="Arial" HorizontalAlignment="Center" Height="24" Text="{Binding Path=Quantity1, Mode=TwoWay}"/>
xaml.cs
public Order()
{
InitializeComponent();
App.ParentWindowRef.ParentFrame.LoadCompleted = NavigationService_LoadCompleted;
}
private void NavigationService_LoadCompleted(object sender, NavigationEventArgs e)
{
RecOrderNo.Text = (string)e.ExtraData;
string RecOrder = (string)e.ExtraData;
string path = Directory.GetCurrentDirectory();
Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();
string file5 = @"" path "\\file5.xlsx";
string OrderNo = "";
Workbook wb5;
Worksheet ws5;
wb5 = excel.Workbooks.Open(file5);
ws5 = wb5.Worksheets[1];
Microsoft.Office.Interop.Excel.Range excelRange5 = ws5.UsedRange;
int rowCount5 = excelRange5.Rows.Count 1;
string FoundItems = "";
MessageBox.Show("Loading");
for (int row5 = 2; row5 < rowCount5; row5 )
{
OrderNo = ws5.Cells[row5, 1].Value.ToString();
if (OrderNo.ToString() == RecOrder.ToString())
{
FoundItems = "Y";
double ItemNo = ws5.Cells[row5, 2].Value;
if (ItemNo == 1)
{
Quantity1.Text = ws5.Cells[row5, 3].Value.ToString();
foreach (Type type in Type1.Items)
{
if (type.Name == ws5.Cells[row5, 4].Value.ToString())
{
Type1.SelectedItem = type;
break;
}
}
foreach (Color color in Color1.Items)
{
if (color.Name == ws5.Cells[row5, 8].Value.ToString())
{
Color1.SelectedItem = color;
break;
}
}
Price1.Text = ws5.Cells[row5, 7].Value.ToString();
Length1.Text = ws5.Cells[row5, 11].Value.ToString();
Total1.Text = ws5.Cells[row5, 12].Value.ToString();
}
}
else
{
if(FoundItems == "Y")
{
break;
}
}
}
wb5.Close(true);
excel.Quit();
Marshal.ReleaseComObject(excel);
}
CodePudding user response:
I would try changing this so that it reads all the values from the excel sheet first, closes the excel document and then populates the variables into the form.
RecOrderNo.Text = (string)e.ExtraData;
string RecOrder = (string)e.ExtraData;
string path = Directory.GetCurrentDirectory();
Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();
string file5 = @"" path "\\file5.xlsx";
string OrderNo = "";
Workbook wb5;
Worksheet ws5;
wb5 = excel.Workbooks.Open(file5);
ws5 = wb5.Worksheets[1];
Microsoft.Office.Interop.Excel.Range excelRange5 = ws5.UsedRange;
int rowCount5 = excelRange5.Rows.Count 1;
string FoundItems = "";
string quantity1Text;
string type1SelectedItem;
string color1SelectedItem;
string price1Text;
string length1Text;
string total1Text;
for (int row5 = 2; row5 < rowCount5; row5 )
{
OrderNo = ws5.Cells[row5, 1].Value.ToString();
if (OrderNo.ToString() == RecOrder.ToString())
{
FoundItems = "Y";
double ItemNo = ws5.Cells[row5, 2].Value;
if (ItemNo == 1)
{
quantity1Text = ws5.Cells[row5, 3].Value.ToString();
foreach (Type type in Type1.Items)
{
if (type.Name == ws5.Cells[row5, 4].Value.ToString())
{
type1SelectedItem = type;
break;
}
}
foreach (Color color in Color1.Items)
{
if (color.Name == ws5.Cells[row5, 8].Value.ToString())
{
color1SelectedItem = color;
break;
}
}
price1Text = ws5.Cells[row5, 7].Value.ToString();
length1Text = ws5.Cells[row5, 11].Value.ToString();
total1Text = ws5.Cells[row5, 12].Value.ToString();
}
}
else
{
if(FoundItems == "Y")
{
break;
}
}
}
wb5.Close(true);
excel.Quit();
Marshal.ReleaseComObject(excel);
Quantity1.Text = quantity1Text;
Type1.SelectedItem = type1SelectedItem;
Color1.SelectedItem = color1SelectedItem;
Price1.Text = price1Text;
Length1.Text = length1Text;
Total1.Text = total1Text;
You might also have a situation where you need to use Invoke
to set the values in the UI, depending on your thread context. Like this:
Invoke(() => {
Quantity1.Text = quantity1Text;
Type1.SelectedItem = type1SelectedItem;
Color1.SelectedItem = color1SelectedItem;
Price1.Text = price1Text;
Length1.Text = length1Text;
Total1.Text = total1Text;
});
CodePudding user response:
After looking at your XAML, I think the issue is that you're mixing binding with direct property setters. Either update the model instead of the Text
property to set it or remove the Text="{Binding Path=Quantity1, Mode=TwoWay}"
attribute