【问题标题】:Using Messaging center xamarin forms PCL to set current objects value使用消息中心 xamarin 形成 PCL 来设置当前对象值
【发布时间】:2017-09-11 20:39:05
【问题描述】:

我有一个场景,我以编程方式创建条目控件。

     foreach (var control in FormInfo.FormElementsInfo)
        {

       case "textbox":
                      //Some code
                      break;


       case "dropdown":

       Entry objDropdown = new Entry();
       objDropdown.HeightRequest = 40;
       objDropdown.StyleId = Convert.ToString(control.ElementId);
       objDropdown.SetBinding(Entry.TextProperty, "ElementValue",BindingMode.TwoWay);
       objDropdown.BindingContext = control;
       layout.Children.Add(objDropdown);

       MessagingCenter.Subscribe<Picklists, string>(objDropdown, "PicklistSelected", (sender, arg) =>
        {
           objDropdown.Text = arg; 
    // I tried this too as this is two way binding. It didn't show the value. 

          //control.ElementValue = arg;



        } );
       break;
     }

如果我单击任何条目,它将打开一个列表视图。一旦我在列表视图中选择了该选项,它将在条目中填充该数据。 但这应该只在当前条目中显示所选值,但它正在更改所有条目中的值。

如何避免这种情况。我希望仅在当前条目中填充所选值。

任何建议将不胜感激。谢谢。

=== 更清楚的问题=====

如果我们使用 2 路绑定以编程方式创建 n 个 Entry 控件。是否可以在其他页面中选择某些内容时更改单个条目值?如果是,如何实现?

【问题讨论】:

  • 您只展示了一个单一条目的案例。您的所有条目是否都绑定到相同的值?如果它们都绑定到相同的值,那么我希望它们都反映变化。
  • @Joshua foreach(FormInfo.FormElementsInfo 中的 var 控件){ //上面的 case 语句 }。上面的case语句在这个for循环中,一切都是一样的。每个条目都绑定到一个名为 Control 的单独对象。我尝试使用代表而不是消息中心,我也有同样的场景。
  • 你能把整个函数贴出来吗?在没有看到实现的其余部分的情况下,我只能假设循环正在遍历所有控件。我看不到您如何链接到列表中的“选定”项目。您绝对不应该在 for 循环中更新绑定。如果在此之前绑定,则该值应该只是更新。
  • @JoshuaPoling 我已经编辑了这个问题。请让我知道这是否清楚。谢谢。
  • 是否可以根据 styleId 在视图上找到控件?

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


【解决方案1】:

首先感谢@Joshua Poling 花时间帮助我。

我认为 MessagingCenter 不适合这种方法。

我为我创建的每个元素分配了一个唯一的 styleId。这基本上存储了堆栈布局中的位置。

我编写了一个委托,它返回选定的值以及元素的位置。因为元素始终是触发此事件的条目。我使用下面的代码来实现这一点。

Entry myentry = (Xamarin.Forms.Entry)layout.Children[src.ElementId];

【讨论】:

    【解决方案2】:

    表单信息

     public class FormInfo
    {
        public List<FormsElementInfo> FormElementsInfo { get; set; }
    }
    

    FormsElementInfo

    public class FormsElementInfo : INotifyPropertyChanged
    {
        private string _elementValue;
        public string ElementValue {
            get => _elementValue;
            set {
                if(_elementValue != value)
                {
                    _elementValue = value;
                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("ElementValue"));
                }
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;
    }
    

    内容页面

     public class ListStackOverflow : ContentPage
    {
        private FormInfo _info = new FormInfo
        {
            FormElementsInfo = new List<FormsElementInfo>()
            {
               new FormsElementInfo { ElementValue = "test 1"},
               new FormsElementInfo { ElementValue = "test 2"},
               new FormsElementInfo { ElementValue = "test 3"},
               new FormsElementInfo { ElementValue = "test 4"},
            }
        };
        private StackLayout _stack = new StackLayout();
        private List<string> _source = new List<string>
        {
            "output 1","output 2","output 3","output 4",
        };
    
        public ListStackOverflow()
        {
            //BindingContext = _info;
    
            foreach(var c in _info.FormElementsInfo)
            {
                Entry tempEntry = new Entry
                {
                    HeightRequest = 40,
                    Placeholder = c.ElementValue,
                    BindingContext = c
                };
                tempEntry.SetBinding(Entry.TextProperty, "ElementValue");
    
                _stack.Children.Add(tempEntry);
            }
            ListView _lv = new ListView { ItemsSource = _source };
            _lv.ItemSelected += Lv_ItemSelected;
    
    
            _stack.Children.Add(_lv);
    
            Content = _stack;
        }
    
        private void Lv_ItemSelected(object sender, SelectedItemChangedEventArgs e)
        {
            var selectedElement = e.SelectedItem.ToString();
            var index = _source.IndexOf(selectedElement);
            var entry = _info.FormElementsInfo[index];
            entry.ElementValue = selectedElement;
        }
    }
    

    输出

    在列表视图中选择相应的索引将更新相同索引的“ElementValue”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多