I am building a C# WinUI 3 desktop app running on Windows 10. I want to use a contentdialog to display error messages.
I am calling this method from multiple catch clauses:
private async void DisplayErrorDialog(string content)
{
ContentDialog ErrorDialog = new ContentDialog()
{
Title = "* Error *",
Content = content,
CloseButtonText = "Ok"
};
// XamlRoot must be set in the case of a ContentDialog running in a Desktop app
ErrorDialog.XamlRoot = this.Content.XamlRoot;
ContentDialogResult result = await ErrorDialog.ShowAsync();
}
Here is how I call the method:
catch (SqlException Sql_Error)
{
Debug.WriteLine($"Hello SQL error GetSQLData_App_View_Results_2020: {Sql_Error.Message}");
DisplayErrorDialog($"GetSQLData_App_View_Results_2020 (SQL Error): {Sql_Error.Message}");
}
catch (Exception Other_Error)
{
Debug.WriteLine($"Hello Other error GetSQLData_App_View_Results_2020: {Other_Error.Message}");
DisplayErrorDialog($"GetSQLData_App_View_Results_2020 (Other Error): {Other_Error.Message}");
}
}
I have many other contentdialogs working successfully within my application. I wanted/needed to test this error contentdialog so I explicitly threw an exception this way:
throw new Exception("SQL test exception #1");
The throw does work and the catch clause 'catches' the exception. However I am getting this error in the contentdialog:
Exception thrown at 0x00007FFFD5FE3FA9 (KernelBase.dll) in MetricReporting.exe: WinRT originate error - 0x80070057 : 'This element is already associated with a XamlRoot, it cannot be associated with a different one until it is removed from the previous XamlRoot.'.
I cannot figure this out. I am a beginner C# and WinUI 3 developer. Thank you for your help and guidance.
- Thank you Andrew for your observation.
Here is more of my code:
public pageResults()
{
this.InitializeComponent();
Debug.WriteLine($"@@@ --- InitializeComponents() Completed --- @@@");
FetchSQLData_Ref_Metric();
FetchSQLData_Ref_Metric_MarketID();
FetchSQLData_StateCodes();
FetchSQLData_MetricYear();
FetchSQLData_Results();
Display_Results();
}
I am doing a lot of sql fetching of data into datatables and then I display the datatable in a datagrid on the page, which is part of a navigationview.
I inserted the 'throw' inside of a method that is inside of 'FetchSQLData_Results()'
private void FetchSQLData_Results()
{
string metricYear = string.Empty;
// Pre-load all views into their own separate datatables. Each views represents a metric year.
// At this time there are views for 2020, 2021, and 2022
foreach (DataRow row in dtMetricYear.Rows)
{
metricYear = row["metricyear"].ToString();
GetSQLData_App_View_Results_(metricYear);
}
}
private void GetSQLData_App_View_Results_(string metricYear)
{
// Load datatables with existing views
switch (metricYear)
{
case "2020":
GetSQLData_App_View_Results_2020();
break;
case "2021":
GetSQLData_App_View_Results_2021();
break;
case "2022":
GetSQLData_App_View_Results_2022();
break;
case "2023":
break;
case "2024":
break;
default:
break;
}
}
The throw is here:
public void GetSQLData_App_View_Results_2020()
{
try
{
using (SqlConnection con = new SqlConnection("Data Source = xxxx; Initial Catalog = xxxx; Integrated Security = True; Connect Timeout = 15; Encrypt = False; TrustServerCertificate = True; ApplicationIntent = ReadWrite; MultiSubnetFailover = False"))
{
**//throw new Exception("SQL test exception #1");**
//Prepare sql
//string sql = "select * from dbo.app_emb_prd_lvl_results_2020 order by metric_id";
string sql = "select * from app_emb_prd_lvl_results_2020 v join dbo.Ref_Metric r on v.metric_id = r.Metric_ID order by v.metric_id";
SqlCommand cmd = new SqlCommand(sql, con);
cmd.CommandType = System.Data.CommandType.Text;
//Open the connection
con.Open();
// Create adapter and fill the datatable with returned data from sql command
using (SqlDataAdapter adap = new SqlDataAdapter(cmd))
{
dtResults2020.Clear();
adap.Fill(dtResults2020);
try
{.. intentionally left blank ..}
catch (Exception List_Error)
{
Debug.WriteLine($"List error GetSQLData_App_View_Results_2020: {List_Error.Message}");
}
Debug.WriteLine($"GetSQLData_App_View_Results_2020 Completed");
} // end using sql adapter
} // end using sql connection
}
catch (SqlException Sql_Error)
{
Debug.WriteLine($"Hello SQL error GetSQLData_App_View_Results_2020: {Sql_Error.Message}");
DisplayErrorDialog($"GetSQLData_App_View_Results_2020 (SQL Error): {Sql_Error.Message}");
}
catch (Exception Other_Error)
{
Debug.WriteLine($"Hello Other error GetSQLData_App_View_Results_2020: {Other_Error.Message}");
DisplayErrorDialog($"GetSQLData_App_View_Results_2020 (Other Error): {Other_Error.Message}");
}
}
As I mentioned in the comments, XamlRoad might not be ready. Try fetching your data in
Loaded
instead of the constructor.