【问题标题】:Xamarin forms custom view dropdown is not workingXamarin 表单自定义视图下拉菜单不起作用
【发布时间】:2018-09-18 21:38:57
【问题描述】:

我正在尝试使用一些可绑定的属性在 xamarin 表单中创建自定义下拉菜单。我使用相对布局在标签下方有一个标签和一个列表视图,因此列表视图将始终位于标签下方,并且其 IsVisible 属性将被切换。

我创建了如下自定义视图:

Dropdown.xaml

<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
         x:Class="CustomViewXam.CustomViews.Dropdown">

  <StackLayout>
    <RelativeLayout>

        <Label x:Name="selectedLabel" TextColor="Red" Text="xcx"
                 BackgroundColor="Silver" FontSize="15" 
                 HeightRequest="50"
                 RelativeLayout.WidthConstraint =
                 "{ConstraintExpression
                 Type=RelativeToParent,
                 Property=Width,
                 Factor=0.5,
                 Constant=0}"/>

        <ListView x:Name="listView" BackgroundColor="Black" 

                           RelativeLayout.WidthConstraint =
                 "{ConstraintExpression
                 Type=RelativeToView,
                 ElementName=selectedLabel,
                 Property=Width,
                 Factor=1,
                 Constant=0}"

                           RelativeLayout.YConstraint=
                 "{ConstraintExpression
                 Type=RelativeToView,
                 ElementName=selectedLabel,
                 Property=Height,
                 Factor=1,
                 Constant=0}"
                 >
        </ListView>            
     </RelativeLayout>
   </StackLayout>
 </ContentView>

Dropdown.xaml.cs

 public partial class Dropdown : ContentView
{
    public Dropdown()
    {
        InitializeComponent();
        BindingContext = this;
    }

    public string TitleText
    {
        get { return base.GetValue(TitleTextProperty).ToString(); }
        set { base.SetValue(TitleTextProperty, value); }
    }

    private static BindableProperty TitleTextProperty = BindableProperty.Create(
        propertyName: "TitleText",
        returnType: typeof(string),
        declaringType: typeof(string),
        defaultValue: "",
        defaultBindingMode: BindingMode.TwoWay,
        propertyChanged: TitleTextPropertyChanged);

    private static void TitleTextPropertyChanged(BindableObject bindable, object oldValue, object newValue)
    {
        var control = (Dropdown)bindable;
        control.selectedLabel.Text = newValue.ToString();
    }

    public static readonly BindableProperty ItemsSourceProperty =
        BindableProperty.Create<Dropdown, IEnumerable<object>>(p => p.ItemsSource,
                                                               null, BindingMode.OneWay, null, (bindable, oldValue, newValue) => { ((Dropdown)bindable).LoadItems(newValue); });


    public IEnumerable<object> ItemsSource
    {
        get { return (IEnumerable<object>)GetValue(ItemsSourceProperty); }
        set { SetValue(ItemsSourceProperty, value); }
    }


    public void LoadItems(IEnumerable<object> tiles)
    {
        try
        {
            var list = tiles;
        }
        catch (Exception e)
        { // can throw exceptions if binding upon disposal
        }

    }
}

我在我的 xaml 页面中使用如下自定义视图

  <local:Dropdown TitleText="dssdasd"  ItemsSource="{Binding TitleList}" />

TitleList 是 ViewModel 中的 ObservableCollection

private ObservableCollection<string> _titleList;  
    public ObservableCollection<string> TitleList
    {  
        get  
        {  
            return _titleList;  
        }  
        set  
        {  
            if (_titleList!= value)  
            {  
                _titleList= value;  
                NotifyPropertyChanged("TitleList");  
            }  
        }  
    }  

问题:

文本在 UI 上可见并且文本正确显示,但下面的列表视图为空且数据未显示。自定义下拉列表中的 LoadItems 方法没有被调用,即使 TitleList 列表已更新。谁能指导我在上面的代码中做错了什么。

注意:我在我的视图中将 BindingContext 设置为我的视图模型。

【问题讨论】:

  • 你应该创建一个 Picker 的自定义渲染器

标签: xamarin xamarin.forms xamarin.ios xamarin.android


【解决方案1】:

注意:我在视图中将 BindingContext 设置为我的视图模型。

你的意思是用你Dropdown的构造方法中的代码来设置吗?

public Dropdown()
{
    InitializeComponent();
    // Try to remove the code below
    BindingContext = this;
}

我建议您在页面 xaml 中设置 BindingContext 并在视图中删除此代码:

public MainPage()
{
    InitializeComponent();

    MyViewModel viewModel = new MyViewModel();
    BindingContext = viewModel;
}

这样LoadItems() 将在我们第一次初始化Dropdown 的ItemsSource 时触发。但是当你想更新列表时,LoadItems() 不会被调用。因为列表的实例没有改变。您可以尝试修改方法,如:

public void LoadItems(IEnumerable<object> tiles)
{
    try
    {
        var list = tiles;
        listView.ItemsSource = tiles;
    }
    catch (Exception e)
    { // can throw exceptions if binding upon disposal
    }

}

此外,如果你想在视图上查看listView的数据,你应该设置它的ItemTemplate,例如:

<ListView.ItemTemplate>
    <DataTemplate>
        <ViewCell>
            <Grid>
                <Label Text="{Binding}"/>
            </Grid>
        </ViewCell>
    </DataTemplate>
</ListView.ItemTemplate>

【讨论】:

  • 感谢您的回复我尝试了上述解决方案及其工作。但是,在我的情况下,自定义视图是 Dropdown,当在任何 xaml 文件中使用时,下拉列表不会与其他视图重叠,它会保留下面隐藏列表视图的空间。
  • @MayankShrivastava 数据是否显示在 listView 中?您可以发布一些屏幕截图和更多详细信息来描述您的问题,这有助于我们了解您的问题。那我们一起来分析一下吧。
  • @MayankShrivastava 嗨,这个变通办法能解决这篇文章的问题吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-22
  • 1970-01-01
  • 2018-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-25
相关资源
最近更新 更多