Как я могу ссылаться на элементы страницы из внешнего класса в Xamarin.Бланки?

#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. Большое вам спасибо! Это прекрасно решило обе мои проблемы 🙂