UPDATE
Свойство IsLocked для сводки в конце ShowDetailPage по той или иной причине препятствует загрузке элементов управления.
У меня есть 2 родительские вкладки, и для каждой вкладки может быть создана одна дочерняя вкладка, и при ее создании дочерний элемент блокируется. Дочерняя вкладка добавляется рядом с индексом родительских вкладок.
У меня есть приложение UWP с управляемой системой меню pivot. У нас есть верхний уровень и второй уровень. На втором уровне некоторые экраны создают представление с помощью команды кнопки для перехода в представление добавления / редактирования, которое заблокировано до нажатия закрытой кнопки, что возвращает его к экрану родительского меню.
По некоторым причинам, когда я закрываю представление добавления / редактирования, некоторые потоки закрываются не сразу, и для закрытия нескольких потоков требуется время. Это создает проблему при попытке перейти в другие родительские вкладки Добавить / редактировать представление. По сути, представление инициализируется еще до того, как элементы управления будут загружены.
Метод ShowDetailPage - это то, что я использую в команде кнопки в представлении, чтобы открыть представление добавления / редактирования. Метод CloseDetailPage - это то, как мы покидаем экран. Индикатор, который говорит мне, что это проблема с многопоточностью, что ошибка передачи страницы возникает только тогда, когда для свойства элемента управления «Инициализировано» задано значение true перед выходом на экран. (Когда он передает правильно, свойство ложно). Также, если я смотрю результаты диагностики, если я жду короткое время, я вижу, как несколько потоков закрываются после закрытия представления, а затем инициализированное свойство всегда ложно, и я могу правильно перемещаться.
Это паттерн, который я замечаю при создании ошибки и ее обходе.
https://imgur.com/a/osgRUCx
Эти страницы закрываются вскоре после того, как я закрываю экран добавления / редактирования. Только если они закрыты, я могу правильно перейти к другому виду добавления / редактирования.
Что я могу сделать, чтобы выяснить, какие потоки вызывают проблему? (Я вижу расположение памяти, но не поток, когда потоки закрываются.)
Если я могу найти потоки, что я могу сделать, чтобы дождаться закрытия потоков, прежде чем разрешить передачу экрана?
NavigationUtility, которая обрабатывает отображение и закрытие нового экрана.
internal static void ShowDetailPage(long customerId, BaseControl control, string parentPageTitle, string detailPageTitle)
{
try
{
Pivot p = MainPage.GetPivot();
Utility u = new Utility();
for (int i = 1; i < p.Items.Count; i++)
{
long customerIdFromPivot = (((p.Items[i] as PivotItem).Content) as Menus).ParentCustomer.CustomerId;
if (CustomerIdFromPivot == CustomerId)
{
var topMenuItem = (((p.Items[i] as PivotItem).Content) as Menus).GetPivot();
if (TopLevelPivots.ContainsKey(CustomerId))
{
TopLevelPivots[CustomerId] = topMenuItem;
}
else
{
TopLevelPivots.Add(CustomerId, topMenuItem);
}
TopLevelPivots[CustomerId].IsLocked = true;
SearchInVisualTree(topMenuItem, CustomerId, parentPageTitle);
var submenus = SecondLevelPivots[CustomerId].ItemsSource;
ObservableCollection<MenuItem> addedMenus = new ObservableCollection<MenuItem>();
int index = 0;
foreach (var subMenuItem in submenus as IEnumerable<MenuItem>)
{
addedMenus.Add(subMenuItem);
if (subMenuItem.HeaderTitle == parentPageTitle)
{
if (DetailScreenParentIndex.ContainsKey(CustomerId))
DetailScreenParentIndex.Remove(CustomerId);
DetailScreenParentIndex.Add(CustomerId, index);
addedMenus.Add(new MenuItem() { HeaderTitle = detailPageTitle, Content = u.GetInitializedControl(control, control.ParentCustomer, addedMenus.Count), ParentCustomer = control.ParentCustomer });
}
index++;
}
SecondLevelPivots[CustomerId].ItemsSource = addedMenus;
//if (DetailScreenParentIndex.ContainsKey(CustomerId))
SecondLevelPivots[CustomerId].SelectedIndex = DetailScreenParentIndex[CustomerId] + 1;
//else
// SecondLevelPivots[CustomerId].SelectedIndex = 0;
SecondLevelPivots[CustomerId].IsLocked = true;
}
}
}
catch (Exception e)
{
}
}
internal static void CloseDetailPage(long CustomerId, string currentPage, string gotoPage)
{
try
{
Pivot p = MainPage.GetPivot();
Utility u = new Utility();
for (int i = 1; i < p.Items.Count; i++)
{
long CustomerIdFromPivot = (((p.Items[i] as PivotItem).Content) as Menus).ParentCustomer.CustomerId;
if (CustomerIdFromPivot == CustomerId)
{
var topMenuItem = (((p.Items[i] as PivotItem).Content) as Menus).GetPivot();
if (TopLevelPivots.ContainsKey(CustomerId))
{
TopLevelPivots[CustomerId] = topMenuItem;
}
else
{
TopLevelPivots.Add(CustomerId, topMenuItem);
}
TopLevelPivots[CustomerId].IsLocked = false;
SearchInVisualTree(topMenuItem, CustomerId, gotoPage);
var submenus = SecondLevelPivots[CustomerId].ItemsSource;
ObservableCollection<MenuItem> addedMenus = new ObservableCollection<MenuItem>();
foreach (var submenuItem in submenus as IEnumerable<MenuItem>)
{
if (submenuItem.HeaderTitle != currentPage)
{
addedMenus.Add(submenuItem);
}
}
SecondLevelPivots[CustomerId].ItemsSource = addedMenus;
SecondLevelPivots[CustomerId].SelectedIndex = DetailScreenParentIndex[claimantId];
SecondLevelPivots[CustomerId].IsLocked = false;
SecondLevelPivots.Remove(CustomerId);
TopLevelPivots.Remove(CustomerId);
DetailScreenParentIndex.Remove(CustomerId);
}
}
}
catch (Exception ex)
{
Utility.LogError(ex);
}
}
ViewModel Команда для нажатия кнопки, чтобы перейти на новый экран.
private void AddCustomerCommandExecute(object obj)
{
bool bEditing = false;
AddEditCustomer control = new AddEditCustomer();
control.ParentCustomer = ParentCustomer;
CustomerDetails customerDetail = obj as CustomerDetails ;
if (customerDetail == null)
{
customerDetail = new CustomerDetails() { };
}
customerDetail.Customer = ParentCustomer;
control.CustomerDetailsForAddEdit = customerDetail;
customerDetail.IsEdit = bEditing;
control.PropertyChanged += CustomersForAddEdit_PropertyChanged;
Utility u = new Utility();
NavigationUtility.ShowDetailPage(ParentCustomer.customerId, u.GetInitializedControl(control, ParentCustomer, 0), "Customers", "Add Customer");
}
Просмотреть код для экрана, который отображается для добавления / редактирования
public sealed partial class AddEditCustomer : BaseControl
{
public AddEditCustomerVM Model { get; set; }
public CustomerDetails CustomerDetailsForAddEdit
{
get { return (CustomerDetails )GetValue(CustomerDetailsForAddEditProperty); }
set
{
SetValue(CustomerDetailsForAddEditProperty, value);
OnPropertyChanged("CustomerDetailsForAddEdit");
}
}
public static readonly DependencyProperty CustomerDetailsForAddEditProperty =
DependencyProperty.Register("CustomerDetailsForAddEdit", typeof(CustomerDetails), typeof(AddEditCustomer), null);
public AddEditCustomer()
{
this.InitializeComponent();
var resource = Resources.FirstOrDefault(aa => aa.Key.ToString() == "AddEditCustomerVM");
if (resource.Value != null)
{
Binding b = new Binding();
b.Mode = BindingMode.TwoWay;
b.Path = new PropertyPath("CustomerDetailsForAddEdit");
b.Source = (resource.Value as AddEditCustomerVM);
Model = (resource.Value as AddEditCustomerVM);
this.SetBinding(CustomerDetailsForAddEditProperty, b);
(resource.Value as AddEditCustomerVM).PropertyChanged += AddEditView_PropertyChanged;
Binding bindVal = new Binding();
bindVal.Mode = BindingMode.TwoWay;
bindVal.Path = new PropertyPath("ParentCustomer");
bindVal.Source = (resource.Value as AddEditCustomerVM);
this.SetBinding(ParentCustomerProperty, bindVal);
}
}
private void AddEditView_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
OnPropertyChanged(e.PropertyName);
}
private void dpStartDate_DateChanged(CalendarDatePicker sender, CalendarDatePickerDateChangedEventArgs args)
{
if (dpEndDate.Date.HasValue)
{
if (args.NewDate.Value > dpEndDate.Date.Value)
dpEndDate.Date = null;
}
}
}