【问题标题】:Set binding from code dont work in xamarin.forms app从代码设置绑定在 xamarin.forms 应用程序中不起作用
【发布时间】:2017-01-11 07:55:12
【问题描述】:

我试图在我的 xamarin.forms 应用程序中使用手风琴。我可以毫无问题地使用它但是当我想将它与 viewmodels 一起使用时。手风琴中没有显示数据 .我的视图模型是这样的;

 namespace xamarinapp
{
   public class TestViewModel : ViewModelBase
    {
        private readonly IServiceWrapper _myServiceWrapper;
        private readonly IAuthenticationService _authenticationService;

        public string viemodelName { get; set; }

        private bool UserLogCheck = false;
        private ObservableRangeCollection<dataInfro> _Acclist;
        public ObservableRangeCollection<Models.dataInfro> Acclist
        {
            get
            {
                return _Acclist;
            }
            set
            {
                _Acclist = value;
                 RaisePropertyChanged(() => Acclist);
            }
        }

        public override async Task InitializeAsync(object navigationData)
        {
            UserLogCheck = DependencyService.Get<LoginInterface>().LoginExists();
            if (!UserLogCheck)
            {
                NavigationService.NavigateToAsync<LoginViewModel>();
            }
            else
            {
              await  getData();
            }
        }
        public ICommand ItemSelectedCommand2 => new Command<dataInfro>(OntaptedItem);
        private async void OntaptedItem(dataInfro item)
        {

            await NavigationService.NavigateToAsync<OgrenciNotViewModel>(item.ogrId.ToString());

        }
        public TestViewModel(IServiceWrapper myServiceWrapper)
        {
            _myServiceWrapper = myServiceWrapper;
            _Acclist = new ObservableRangeCollection<dataInfro>();

        }
        private async Task getData()
        {
            ServiceWrapper serviceWrapper = new ServiceWrapper();
            var loginUser = DependencyService.Get<LoginInterface>().getAccount();
            var data =  await _myServiceWrapper.GetDataSecure<Ogrencilik>("GetDataUrl", loginUser);
            Acclist =new ObservableRangeCollection<dataInfro>(data.dataCollect);
        }
    }

}

而手风琴自定义控件是这样的。(来自https://kimsereyblog.blogspot.com.tr/2016/10/build-accordion-view-in-xamarinforms.html

namespace xamarinapp
{
    public class DefaultTemplate : AbsoluteLayout
    {
        public DefaultTemplate()
        {
            this.Padding = 0;
            this.HeightRequest = 50;
            var title = new Label { HorizontalTextAlignment = TextAlignment.Start, HorizontalOptions = LayoutOptions.StartAndExpand };
            var price = new Label { HorizontalTextAlignment = TextAlignment.End, HorizontalOptions = LayoutOptions.End };
            this.Children.Add(title, new Rectangle(0, 0.5, 0.5, 1), AbsoluteLayoutFlags.All);
            this.Children.Add(price, new Rectangle(1, 0.5, 0.5, 1), AbsoluteLayoutFlags.All);
            title.SetBinding(Label.TextProperty, "name", stringFormat: "{0:c1}");
            price.SetBinding(Label.TextProperty, "balance", stringFormat: "{0:C2}");
        }
    }

    public class AccordionView : ScrollView
    {
        private StackLayout _layout = new StackLayout { Spacing = 1 };

        public DataTemplate Template { get; set; }
        public DataTemplate SubTemplate { get; set; }

        public static readonly BindableProperty ItemsSourceProperty =
            BindableProperty.Create(
                propertyName: "ItemsSource",
                returnType: typeof(IList),
                declaringType: typeof(AccordionSectionView),
                defaultValue: default(IList),
                propertyChanged: AccordionView.PopulateList);

        public IList ItemsSource
        {
            get { return (IList)GetValue(ItemsSourceProperty); }
            set { SetValue(ItemsSourceProperty, value); }
        }

        public AccordionView()
        {
            var itemTemplate = new DataTemplate(typeof(DefaultTemplate));
            this.SubTemplate = itemTemplate;
            this.Template = new DataTemplate(() => (object)(new AccordionSectionView(itemTemplate, this)));
            this.Content = _layout;
        }

        void PopulateList()
        {
            _layout.Children.Clear();

            foreach (object item in this.ItemsSource)
            {
                var template = (View)this.Template.CreateContent();
                template.BindingContext = item;
                _layout.Children.Add(template);
            }
        }

        static void PopulateList(BindableObject bindable, object oldValue, object newValue)
        {
            if (oldValue == newValue) return;
            ((AccordionView)bindable).PopulateList();
        }
    }

    public class AccordionSectionView : StackLayout
    {
        private bool _isExpanded = false;
        private StackLayout _content = new StackLayout { HeightRequest = 0 };
        private Color _headerColor = Color.FromHex("0067B7");
        private ImageSource _arrowRight = ImageSource.FromFile("ic_keyboard_arrow_right_white_24dp.png");
        private ImageSource _arrowDown = ImageSource.FromFile("ic_keyboard_arrow_down_white_24dp.png");
        private AbsoluteLayout _header = new AbsoluteLayout();
        private Image _headerIcon = new Image { VerticalOptions = LayoutOptions.Center };
        private Label _headerTitle = new Label { TextColor = Color.White, VerticalTextAlignment = TextAlignment.Center, HeightRequest = 50 };
        private DataTemplate _template;

        public static readonly BindableProperty ItemsSourceProperty =
            BindableProperty.Create(
                propertyName: "ItemsSource",
                returnType: typeof(IList),
                declaringType: typeof(AccordionSectionView),
                defaultValue: default(IList),
                propertyChanged: AccordionSectionView.PopulateList);

        public IList ItemsSource
        {
            get { return (IList)GetValue(ItemsSourceProperty); }
            set { SetValue(ItemsSourceProperty, value); }
        }

        public static readonly BindableProperty TitleProperty =
            BindableProperty.Create(
                propertyName: "Title",
                returnType: typeof(string),
                declaringType: typeof(AccordionSectionView),
                propertyChanged: AccordionSectionView.ChangeTitle);

        public string Title
        {
            get { return (string)GetValue(TitleProperty); }
            set { SetValue(TitleProperty, value); }
        }

        public AccordionSectionView(DataTemplate itemTemplate, ScrollView parent)
        {
            _template = itemTemplate;
            _headerTitle.BackgroundColor = _headerColor;
            _headerIcon.Source = _arrowRight;
            _header.BackgroundColor = _headerColor;

            _header.Children.Add(_headerIcon, new Rectangle(0, 1, .1, 1), AbsoluteLayoutFlags.All);
            _header.Children.Add(_headerTitle, new Rectangle(1, 1, .9, 1), AbsoluteLayoutFlags.All);

            this.Spacing = 0;
            this.Children.Add(_header);
            this.Children.Add(_content);

            _header.GestureRecognizers.Add(
                new TapGestureRecognizer
                {
                    Command = new Command(async () =>
                    {
                        if (_isExpanded)
                        {
                            _headerIcon.Source = _arrowRight;
                            _content.HeightRequest = 0;
                            _content.IsVisible = false;
                            _isExpanded = false;
                        }
                        else
                        {
                            _headerIcon.Source = _arrowDown;
                            _content.HeightRequest = _content.Children.Count * 50;
                            _content.IsVisible = true;
                            _isExpanded = true;

                            // Scroll top by the current Y position of the section
                            if (parent.Parent is VisualElement)
                            {
                                await parent.ScrollToAsync(0, this.Y, true);
                            }
                        }
                    })
                }
            );
        }

        void ChangeTitle()
        {
            _headerTitle.Text = this.Title;
        }

        void PopulateList()
        {
            _content.Children.Clear();

            foreach (object item in this.ItemsSource)
            {
                var template = (View)_template.CreateContent();
                template.BindingContext = item;
                _content.Children.Add(template);
            }
        }

        static void ChangeTitle(BindableObject bindable, object oldValue, object newValue)
        {
            if (oldValue == newValue) return;
            ((AccordionSectionView)bindable).ChangeTitle();
        }

        static void PopulateList(BindableObject bindable, object oldValue, object newValue)
        {
            if (oldValue == newValue) return;
            ((AccordionSectionView)bindable).PopulateList();
        }
    }
}

我正在尝试像这样设置绑定

 [XamlCompilation(XamlCompilationOptions.Skip)]
    public partial class PageOgrenciNotModal : ContentPage
    {
        public PageOgrenciNotModal()
        {
            InitializeComponent();
        }
        protected override void OnBindingContextChanged()
        {
            base.OnBindingContextChanged();
            Accorview.SetBinding(AccordionView.ItemsSourceProperty, "Acclist");
            Accorview.Template.SetBinding(AccordionSectionView.TitleProperty, "Title");
            Accorview.Template.SetBinding(AccordionSectionView.ItemsSourceProperty, "List");
        }
    }

但是什么都没有发生。(注意:获取数据没有问题,我可以使用与 listview 相同的方法没有问题)。感谢任何帮助,谢谢

【问题讨论】:

    标签: c# mvvm xamarin xamarin.forms


    【解决方案1】:

    如果你没有使用 MVVM 框架,你必须自己设置页面的BindingContext

    所以做一些类似的事情:

    public PageOgrenciNotModal()
    {
        InitializeComponent();
        BindingContext = new TestViewModel();
    
    }
    

    【讨论】:

    • 是的,我知道,我在导航时这样做。所以在页面中设置视图模型没有问题。
    • 您说“我在导航时这样做”是什么意思?您应该始终在构造函数中设置 BindingContext,而我们在上面的代码中没有看到。
    【解决方案2】:

    这个

    Accorview.SetBinding(ListView.ItemsSourceProperty, "Accorlist");
    

    看起来很可疑。

    恕我直言,应该是

    Accorview.SetBinding(AccordionView.ItemsSourceProperty, "Accorlist");
    

    【讨论】:

    • 对不起,我在这里写错了,我已经用这种方式了。我试图通过从代码中绑定一个listview来检查数据是否来自,没有问题,因为listview被绑定了。
    猜你喜欢
    • 2017-11-02
    • 1970-01-01
    • 2016-05-16
    • 2019-12-10
    • 1970-01-01
    • 2022-01-14
    • 2018-12-09
    • 2019-04-29
    相关资源
    最近更新 更多