Настройка макетов Xamarin.Forms

Я создаю приложение для Android и iOS, используя Xamarin Forms.

Что я просто пытаюсь сделать, так это установить фон, который можно рисовать в моем приложении Android для моих ListView элементов. Корневой вид моих ListView элементов - это StackLayout:

var listView = new ListView
{
    ItemsSource = items,
    ItemTemplate = new DataTemplate(() =>
    {
        return new ViewCell
        {
            View = new StackLayout(...)
        };
    }
};

Я знаю, что могу получить доступ к собственному элементу с помощью пользовательского средства визуализации:

public class MyEntryRenderer : EntryRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
    {
        base.OnElementChanged(e);

        if (e.OldElement == null) {
            var nativeEditText = (EditText)Control;
            ...
        }
    }
}

Но я не уверен, как это будет работать для StackLayout (или любого другого макета в этом отношении).

Сначала я расширил StackLayout:

public class ListViewItem : StackLayout
{
}

И я где-то читал, что макеты используют VisualElementRenderer, поэтому я попробовал следующее:

public class ListViewItemRenderer : VisualElementRenderer<StackLayout>
{
    protected override void OnElementChanged(ElementChangedEventArgs<StackLayout> e)
    {
        base.OnElementChanged(e);

        // any way to access the native element?
    }
}

Но VisualElementRenderer похоже не дает мне доступа к нативному элементу.

Итак, есть ли способ получить доступ к собственным элементам элементов макета? Или, может быть, есть другой способ просто установить фон, который можно рисовать на макетах в моем приложении для Android?


person sroes    schedule 12.08.2014    source источник


Ответы (2)


Несмотря на то, что я до сих пор не знаю, как получить доступ к нативному элементу макета, у VisualElementRenderer есть метод для установки фона, который можно рисовать на Android (это было именно то, что мне было нужно). Итак, я закончил со следующим:

protected override void OnElementChanged(ElementChangedEventArgs<StackLayout> e)
{
    base.OnElementChanged(e);
    SetBackgroundDrawable(Resources.GetDrawable(Resource.Drawable.listViewItem));
}
person sroes    schedule 13.08.2014
comment
VisualElementRenderer имеет свойство Element, которое возвращает собственный элемент. - person Rodja; 11.09.2014
comment
как добиться того же в iOS?? - person umakanta; 11.11.2014
comment
Привет, я знаю, что это старый пост. Но не могли бы вы предоставить мне весь исходный код Android, который вы использовали. включая шаблон данных списка и визуализатор стека. ПОЖАЛУЙСТА! - person Guy Micciche; 11.02.2016

Насколько я понимаю, вы хотите подключиться к существующему модулю визуализации макета и расширить его, чтобы получить доступ к собственному элементу с дополнительными возможностями, такими как фоновое изображение.

Со временем поддержка background-image будет поддерживаться точно так же, как background-color, я полагаю, в элементах управления Layout. Возможно, стоит подождать этого, поскольку я не понимаю, почему они не реализуют это в более позднем выпуске.

В то же время вам нужно что-то, что будет работать и довольно легко реализовать?

Поэтому создание фонового рисунка путем наследования средства визуализации от макета может быть не самым простым решением, хотя у него есть свои преимущества, поскольку вы можете легко повторно использовать дополнительные функции во всех макетах. для приложения.

Однако в вашем коде для ListViewItemRenderer он наследуется от элемента управления Xamarin.Forms (вы указали StackLayout) и не указали собственный, зависящий от платформы элемент управления, который должен быть основой для элемента управления макетом, который должен соответствовать используемому элементу управления Xamarin.Forms, зависящему от платформы.

Каждый Renderer привязан к нативному элементу. Элементы управления Layout ничем не отличаются от других средств визуализации собственных собственных элементов управления.

Для пользовательского элемента управления вы напишете средство визуализации, подобное следующему (обратите внимание, что я не указал средство визуализации layout, так как мне еще не нужно было это делать, и я просто исхожу из прошлого опыта - но аналогичные правила должны применяться к реализации рендерера для макета, а не к пользовательскому элементу управления):-

// System.Windows.Controls.Grid in this case is the root native control for a WindowsPhone renderer of MyControl
public class MyControlRenderer : ViewRenderer<MyControlView, System.Windows.Controls.Grid>

Однако существует более простой подход для достижения того, что вы хотите сделать: -

Более простой подход заключается в том, чтобы вместо наследования от элемента управления Stack Layout было бы лучше наследовать от Grid как корня элемента управления.

Затем вы можете добавить элемент управления Image в Grid, а также Stack Layout для той же Grid Строка и Столбец.

Сделав вышеизложенное, вы сможете получить фоновое изображение по всей строке элемента списка.

person Pete    schedule 12.08.2014
comment
Спасибо за ответ. Если только VisualElementRenderer не является подходящим средством визуализации для макетов, я думаю, что средства визуализации для макетов отличаются от средств визуализации пользовательских элементов управления. VisualElementRenderer не предоставляет мне свойство (Control) для доступа к собственному элементу управления. - person sroes; 12.08.2014
comment
Grid и StackLayout являются производными от Layout‹View›. Я предполагаю, что вам нужно создать производную от ViewRenderer, так как это ярлык для ViewRenderer‹View, RootNativeControlUsedForLayout›, а затем применить Export на этом, чтобы ваша реализация пользовательского класса вызывалась и выполнялась. После этого вы сможете в своей собственной реализации ViewRenderer добавить эту дополнительную поддержку для фонового изображения, получая доступ к собственному корневому элементу управления, подходящему для каждой платформы. - person Pete; 12.08.2014
comment
Я предполагаю, что StackLayout будет отображаться как LinearLayout на Android. Итак, я попробовал public class ListViewItemRenderer : ViewRenderer<StackLayout, LinearLayout>, но Control остается нулевым. - person sroes; 13.08.2014
comment
Это имело бы смысл, однако они указывают базу для Android только как View, поскольку они также позволяют рендереру охватывать различные макеты< /б>. Я только что увидел, что вам удалось найти обходной путь, однако, если вы последуете приведенному выше совету, он действительно сработает и позволит вам настроить его с получением корневого доступа к native< /b> элемент. - person Pete; 13.08.2014