Xamarin условно отображается в производном ControlTemplate ContentPresenter

Не совсем нашел то, что ищу. Новичок в разработке любого типа для Android / iPhone, но у него есть опыт работы с WPF с шаблонами элементов управления, стилями и работой с xaml.

Вот пример изображения того, что я пытаюсь выполнить, но не могу заставить его работать с привязками. У меня есть шаблон управления, который дает мне верхнее изображение. Заголовок / метка вверху и 3 кнопки справа, а затем «ContentPresenter». Все они работают сами по себе с базовым классом, для которого они определены. (шаблон управления упрощен для публикации)

<ControlTemplate x:Key="MyCommonTemplate" >
    <StackLayout>
        <StackLayout Orientation="Horizontal">
            <Label Text="{TemplateBinding Title}" />
            <Button Text="x" />
            <Button Text="y" />
            <Button Text="z" />
        </StackLayout>

        <ContentPresenter/>
    </StackLayout>
</ControlTemplate>

<Style TargetType="{x:Type myApp:MyCommonControl}" x:Key="MyCommonStyle">
    <Style.Setters>
        <Setter Property="ControlTemplate" Value="{StaticResource MyCommonTemplate}" />
    </Style.Setters>
</Style>

Чего я пытаюсь достичь

Теперь ДВА изображения под верхним образцом шаблона. Каждый из них является производным от верхнего шаблона, но каждый из них имеет собственное внутреннее содержимое, в котором представлен презентатор содержимого. Как показано на изображении, содержимое первого производного элемента управления должно отображаться всегда, но во втором оно состоит из ДВУХ частей. Один показывать всегда, другой показывать условно.

Это будет представлять первый производный элемент управления из того же шаблона элемента управления. Content Presenter правильно отражает внутреннее содержимое, как на изображении.

<?xml version="1.0" encoding="UTF-8"?>
<myApp:MyCommonControl
    x:Class="MyApp.MySubControl1"
    ...
    xmlns:myapp="clr-namespace:MyApp">

    <!-- This properly shows within the "ContentPresenter" as expected -->
    <StackLayout>
        <Label Text="Always show..." />
        <Label Text="for this..." />
    </StackLayout>
</myApp:MyCommonControl>

Теперь второй производный элемент управления

<?xml version="1.0" encoding="UTF-8"?>
<myApp:MyCommonControl
    x:Class="MyApp.MySubControl2"
    ...
    xmlns:myapp="clr-namespace:MyApp">

    <!-- This properly shows within the "ContentPresenter" as expected -->
    <StackLayout>
        <Label Text="Different sub-panel..." />
        <Label Text="Always show..." />
    </StackLayout>

    <StackLayout IsVisible="{TemplateBinding OkToShowThis}">
        <Label Text="This secondary sub-panel..." />
        <Label Text="Based on..." />
    </StackLayout>    
</myApp:MyCommonControl>

Фактический базовый класс MyCommonControl имеет множество

public static readonly BindableProperty…

из них тип данных bool "OkToShowThis". Что касается верхней надписи и области общих кнопок, все они, соответственно, распознали, что их вид изменен с видимого на скрытый, когда это необходимо, поэтому я ЗНАЮ, что они работают.

Моя проблема связана с производным элементом управления, который заполняется из ContentPresenter базового шаблона элемента управления. «OkToShowThis» этого дочернего элемента управления НЕ обновляется. Не уверен, что в этом сценарии правильная ссылка на привязку.

Ценю любую помощь.

ОЦЕНКА РЕШЕНИЯ

Благодаря решению, предложенному Лео Чжу, моя интерпретация работает следующим образом. Самый внешний xaml, где

x:Name=myCommonControl

относится к КОНКРЕТНОМУ экземпляру созданного класса. Оттуда я могу привязать конкретный ВНУТРЕННИЙ КОНТРОЛЬ к этому объекту через

<StackLayout BindingContext="{x:Reference Name=myCommonControl}" 

Теперь, когда у меня есть правильная привязка к экземпляру класса, известная как «Name = myCommonControl», я могу ссылаться на любое свойство этого экземпляра класса, тем самым завершая свою потребность через

<StackLayout BindingContext="{x:Reference Name=myCommonControl}" 
    IsVisible="{Binding OkToShowThis}">

И внутренний элемент управления будет динамически отображаться / скрываться, как и ожидалось. Большое спасибо.


person DRapp    schedule 15.08.2019    source источник


Ответы (1)


сначала в своем MyCommonControl вы можете определить BindableProperty OkToShowThis:

public static readonly BindableProperty OkToShowThisProperty = BindableProperty.Create("OkToShowThis", typeof(bool), typeof(MyCommonControl), true);
public bool OkToShowThis
    {
        get { return (bool)GetValue(OkToShowThisProperty); }
    }

затем во втором производном элементе управления:

<?xml version="1.0" encoding="UTF-8"?>
<myApp:MyCommonControl
    x:Class="MyApp.MySubControl2"
    ...
    xmlns:myapp="clr-namespace:MyApp"
    OkToShowThis ="False"   
    x:Name="myCommonControl"
    >

   <!-- This properly shows within the "ContentPresenter" as expected -->
   <StackLayout>
      <Label Text="Different sub-panel..." />
      <Label Text="Always show..." />        
      <StackLayout BindingContext="{x:Reference Name=myCommonControl}"  IsVisible="{Binding OkToShowThis}">
         <Label Text="This secondary sub-panel..." />
         <Label Text="Based on..." />
      </StackLayout> 
   </StackLayout>

is this what you want ?

person Leo Zhu - MSFT    schedule 16.08.2019
comment
СПАСИБО РАБОТАЛО ОТЛИЧНО !! Обновил мой исходный пост о моей интерпретации привязки, чтобы помочь другим, которые могут не понимать частей ... Надеюсь, мое обучение может помочь другим, исходя из вашего ответа. - person DRapp; 16.08.2019