#c# #xamarin.forms
Вопрос:
У меня есть несколько страниц в моем Xamarin.Приложения форм, которые требуют аналогичной функциональности, поэтому я решил создать внешний служебный класс, на который я могу ссылаться во всех из них, чтобы уменьшить избыточность кода.
Код для одной из страниц таков:
public partial class Incontrol_page : TabbedPage
{
public Incontrol_page()
{
Boolean initialrun = true;
Alert_Generator generator = new Alert_Generator();
InitializeComponent();
Task.Run(() =>
{
while (true)
{
//code not relevant to the question removed here
Device.BeginInvokeOnMainThread(() =>
{
List<Frame> offline_alerts = generator.GenAlerts("incontrol_offline", active_offline_events);
List<Frame> bandwidth_alerts = generator.GenAlerts("incontrol_bandwidth", active_bandwidth_events);
offline_stack.Children.Clear();
bandwidth_stack.Children.Clear();
foreach(Frame frame in offline_alerts)
{
offline_stack.Children.Add(frame);
}
foreach(Frame frame in bandwidth_alerts)
{
bandwidth_stack.Children.Add(frame);
}
});
Thread.Sleep(10000);
}
});
}
}
По сути, метод извлекает данные из API и создает список кадров, которые немного отличаются в зависимости от типа извлекаемых данных. Эта часть работает нормально, однако я сталкиваюсь с проблемами функциональности в самих кадрах. Вот пример кода, используемого для создания кадров:
public List<Frame> GenAlerts(string type, List<String> active_events)
{
using (WebClient wc = new WebClient())
{
//irrelevant code removed
foreach (var obj in list)
{
//irrelevant code removed
Frame alert_frame = new Frame
{
//irrelevant code removed
Content = new StackLayout
{
//irrelevant code removed
Children =
{
Orientation=Xamarin.Forms.StackOrientation.Horizontal,
Children =
{
GetChildren(obj,color,wc,type)[0],
GetChildren(obj,color,wc,type)[1]
}
}
}
};
return_list.Add(alert_frame);
}
return return_list;
}
}
public List<View> GetChildren(Alert obj, Color color, WebClient wc, string type)
{
//creates info button with popup for the event readout
Button info = new Button()
{
//attributes here
};
info.Clicked = async (sender, args) => await DisplayAlert("Event Info", obj.Change, "Okay");
//creates delete button that deletes the parent alert object from the stack layout and sends the command to the api to remove it from the SQL table
Button delete = new Button()
{
//attributes here
};
delete.Clicked = async (sender, args) => await Remove(obj, wc, type);
List<View> alert_frames = new List<View>();
alert_frames.Add(info);
alert_frames.Add(delete);
return alert_frames;
}
async Task Remove(Alert obj, WebClient wc, string type)
{
View frame = new Frame();
foreach (Frame element in alert_stack.Children)
{
if (element.StyleId == obj.EventKey)
{
frame = element;
}
}
alert_stack.Children.Remove(frame);
//sends the remove command for the event's id to the api
var jsonstr = wc.DownloadString("http://172.30.211.33:5000/remove?db=" type "amp;id=" obj.EventKey);
}
Большие проблемы для меня возникают в задаче Удаления(объект оповещения, WebClient wc, строковый тип). В предыдущей реализации, когда все это было непосредственно в коде для каждой страницы, а не в многоразовом методе, я смог просто получить ссылку на родительский фрейм и удалить нужный элемент нажатием кнопки, но это не так просто из внешнего метода, не прикрепленного непосредственно к странице. Могу ли я передать ссылку на alert_stack в качестве аргумента GenAlerts()?
В том же духе я не уверен, как я могу заставить вызов функции DisplayAlert() фактически работать из внешнего метода. Есть ли способ, которым я могу получить ссылку на родительскую страницу, вызывающую функцию, чтобы она действительно отображала предупреждение на экране?
Ответ №1:
могу ли я передать ссылку на alert_stack в качестве аргумента GenAlerts()?
ДА. Вы пробовали? Это должно быть так просто, как
List<Frame> offline_alerts = generator.GenAlerts(offline_stack, "incontrol_offline", active_offline_events);
и
public List<Frame> GenAlerts(StackLayout parent, string type, List<String> active_events)
Есть ли способ, которым я могу получить ссылку на родительскую страницу
ДА. Вы можете либо передать явную ссылку на текущую страницу, либо сделать это
App.Current.MainPage.DisplayAlert(...);
Комментарии:
1. Большое вам спасибо! Это прекрасно решило обе мои проблемы 🙂