当其他控件放置在datagrid列中时,它没有绑定

问题描述 投票:1回答:1

我正在研究基于this one的数据网格示例。

 <dg:DataGrid x:Name="datagrid" ItemsSource="{Binding Teams}"  SelectionEnabled="True" SelectedItem="{Binding SelectedTeam}" ActiveRowColor="Red"
                         RowHeight="70" HeaderHeight="50" BorderColor="#CCCCCC" HeaderBackground="#E0E6F8" Focused="Datagrid_Focused"
                         PullToRefreshCommand="{Binding RefreshCommand}" IsRefreshing="{Binding IsRefreshing}"
                         >
                <x:Arguments>
                    <ListViewCachingStrategy>RetainElement</ListViewCachingStrategy>
                </x:Arguments>
                <dg:DataGrid.HeaderFontSize>
                    <OnIdiom  x:TypeArguments="x:Double">
                        <OnIdiom.Tablet>15</OnIdiom.Tablet>
                        <OnIdiom.Phone>12</OnIdiom.Phone>
                    </OnIdiom>
                </dg:DataGrid.HeaderFontSize>
                <dg:DataGrid.Columns>
                    <dg:DataGridColumn Title="Logo" PropertyName="Logo" Width="100" SortingEnabled="False">
                        <dg:DataGridColumn.CellTemplate>
                            <DataTemplate>
                                <Image Source="{Binding}" HorizontalOptions="Center" VerticalOptions="Center" Aspect="AspectFit" HeightRequest="60" />
                            </DataTemplate>
                        </dg:DataGridColumn.CellTemplate>
                    </dg:DataGridColumn>
                    <dg:DataGridColumn Title="Team" PropertyName="Name" Width="2*">
                        <dg:DataGridColumn.CellTemplate>
                            <DataTemplate>
                                <Grid x:Name="gridtest" BindingContext="{Binding .}">
                                    <Grid.GestureRecognizers>
                                        <TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped"/>
                                    </Grid.GestureRecognizers>

                                    <Label x:Name="label1" Text="{Binding Name,Mode=TwoWay}" />
                                    <Editor x:Name="editorTest" Completed="Editor_Completed" BindingContext="{Binding .}" Focused="Editor_Focused">
                                    </Editor>
                                </Grid>
                            </DataTemplate>
                        </dg:DataGridColumn.CellTemplate>
                    </dg:DataGridColumn>
                    <dg:DataGridColumn Title="Win" PropertyName="Win" Width="0.95*"/>
                    <dg:DataGridColumn Title="Loose" PropertyName="Loose"  Width="1*"/>
                    <dg:DataGridColumn PropertyName="Home">
                        <dg:DataGridColumn.FormattedTitle>
                            <FormattedString>
                                <Span Text="Home" ForegroundColor="Black" FontSize="13" FontAttributes="Bold"/>
                                <Span Text=" (win-loose)" ForegroundColor="#333333" FontSize="11" />
                            </FormattedString>
                        </dg:DataGridColumn.FormattedTitle>
                    </dg:DataGridColumn>
                    <dg:DataGridColumn Title="Percentage" PropertyName="Percentage" StringFormat="{}{0:0.00}" />

                </dg:DataGrid.Columns>


            </dg:DataGrid>

我有一个团队模型,我在编辑器中输入的名称应绑定在该模型属性中。在静态情况下,它可以正常工作。如何在动态情况下实现效果,

我有添加按钮。仅在添加按钮中,我要将项目添加到集合团队中,

private void AddButton_Clicked(object sender, EventArgs e)
{
    viewModel.Teams.Add(new Models.Team()
    {
         Win = 73,
         Name = "",
         Loose = 9,
         Percentage = 0.89,
         Conf = "46-6",
         Div = "15-1",
         Home = "39-2",
         Road = "34-7",
         Last10 = "8-2",
         Streak = "W 4",
         Logo = "gsw.png"
    });
}

打开编辑器时,datagrid selectedItem事件不起作用。文本未绑定到模型属性Name。

单击保存按钮时,我需要更新的收藏集。

如何实现这种情况?

c# xamarin xamarin.forms datagrid
1个回答
0
投票

由于您已使用MVVM,因此您应该处理ViewModel中的所有逻辑。您可以在模型中绑定Ed​​itorText

<Editor Text="{Binding editorText,Mode=TwoWay}"... />

在模型中

定义新属性

public class Team  : INotifyPropertyChanged
{

    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged(string property)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(property));
    }


    string editorText;
    public string EditorText
    {
        get
        {
            return editorText;
        }
        set
        {
            if(value!=null)
            {
                editorText = value;
                OnPropertyChanged("EditorText");
            }
        }
    }
    //...
  }

打开编辑器时,datagrid selectedItem事件不起作用。

这可能是插件的问题。您可以在编辑器聚焦时设置SelectItem

在您的项目中添加以下课程

using System;
using Xamarin.Forms;

namespace xxx
{
    public class BehaviorBase<T> : Behavior<T> where T : BindableObject
    {
        public T AssociatedObject { get; private set; }

        protected override void OnAttachedTo (T bindable)
        {
            base.OnAttachedTo (bindable);
            AssociatedObject = bindable;

            if (bindable.BindingContext != null) {
                BindingContext = bindable.BindingContext;
            }

            bindable.BindingContextChanged += OnBindingContextChanged;
        }

        protected override void OnDetachingFrom (T bindable)
        {
            base.OnDetachingFrom (bindable);
            bindable.BindingContextChanged -= OnBindingContextChanged;
            AssociatedObject = null;
        }

        void OnBindingContextChanged (object sender, EventArgs e)
        {
            OnBindingContextChanged ();
        }

        protected override void OnBindingContextChanged ()
        {
            base.OnBindingContextChanged ();
            BindingContext = AssociatedObject.BindingContext;
        }
    }
}
using System;
using System.Reflection;
using System.Windows.Input;
using Xamarin.Forms;

namespace xxx
{
    public class EventToCommandBehavior : BehaviorBase<View>
    {
        Delegate eventHandler;

        public static readonly BindableProperty EventNameProperty = BindableProperty.Create ("EventName", typeof(string), typeof(EventToCommandBehavior), null, propertyChanged: OnEventNameChanged);
        public static readonly BindableProperty CommandProperty = BindableProperty.Create ("Command", typeof(ICommand), typeof(EventToCommandBehavior), null);
        public static readonly BindableProperty CommandParameterProperty = BindableProperty.Create ("CommandParameter", typeof(object), typeof(EventToCommandBehavior), null);
        public static readonly BindableProperty InputConverterProperty = BindableProperty.Create ("Converter", typeof(IValueConverter), typeof(EventToCommandBehavior), null);

        public string EventName {
            get { return (string)GetValue (EventNameProperty); }
            set { SetValue (EventNameProperty, value); }
        }

        public ICommand Command {
            get { return (ICommand)GetValue (CommandProperty); }
            set { SetValue (CommandProperty, value); }
        }

        public object CommandParameter {
            get { return GetValue (CommandParameterProperty); }
            set { SetValue (CommandParameterProperty, value); }
        }

        public IValueConverter Converter {
            get { return (IValueConverter)GetValue (InputConverterProperty); }
            set { SetValue (InputConverterProperty, value); }
        }

        protected override void OnAttachedTo (View bindable)
        {
            base.OnAttachedTo (bindable);
            RegisterEvent (EventName);
        }

        protected override void OnDetachingFrom (View bindable)
        {
            DeregisterEvent (EventName);
            base.OnDetachingFrom (bindable);
        }

        void RegisterEvent (string name)
        {
            if (string.IsNullOrWhiteSpace (name)) {
                return;
            }

            EventInfo eventInfo = AssociatedObject.GetType ().GetRuntimeEvent (name);
            if (eventInfo == null) {
                throw new ArgumentException (string.Format ("EventToCommandBehavior: Can't register the '{0}' event.", EventName));
            }
            MethodInfo methodInfo = typeof(EventToCommandBehavior).GetTypeInfo ().GetDeclaredMethod ("OnEvent");
            eventHandler = methodInfo.CreateDelegate (eventInfo.EventHandlerType, this);
            eventInfo.AddEventHandler (AssociatedObject, eventHandler);
        }

        void DeregisterEvent (string name)
        {
            if (string.IsNullOrWhiteSpace (name)) {
                return;
            }

            if (eventHandler == null) {
                return;
            }
            EventInfo eventInfo = AssociatedObject.GetType ().GetRuntimeEvent (name);
            if (eventInfo == null) {
                throw new ArgumentException (string.Format ("EventToCommandBehavior: Can't de-register the '{0}' event.", EventName));
            }
            eventInfo.RemoveEventHandler (AssociatedObject, eventHandler);
            eventHandler = null;
        }

        void OnEvent (object sender, object eventArgs)
        {
            if (Command == null) {
                return;
            }

            object resolvedParameter;
            if (CommandParameter != null) {
                resolvedParameter = CommandParameter;
            } else if (Converter != null) {
                resolvedParameter = Converter.Convert (eventArgs, typeof(object), null, null);
            } else {
                resolvedParameter = eventArgs;
            }       

            if (Command.CanExecute (resolvedParameter)) {
                Command.Execute (resolvedParameter);
            }
        }

        static void OnEventNameChanged (BindableObject bindable, object oldValue, object newValue)
        {
            var behavior = (EventToCommandBehavior)bindable;
            if (behavior.AssociatedObject == null) {
                return;
            }

            string oldEventName = (string)oldValue;
            string newEventName = (string)newValue;

            behavior.DeregisterEvent (oldEventName);
            behavior.RegisterEvent (newEventName);
        }
    }
}

在xaml中

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:local="clr-namespace:xxx"
             mc:Ignorable="d"
             x:Name="page"  // set name here
             x:Class="xxx.MainPage">
<Editor.Behaviors>
    <local:EventToCommandBehavior EventName="Focused" Command="{Binding Source={x:Reference page},Path=BindingContext.xxxCommand}" CommandParameter="{Binding }" />

</Editor.Behaviors>

在ViewModel中]
xxxCommand = new Command((model)=>{

   var item = model as Team;
   SelectedTeam = item;
   //  ...
});

© www.soinside.com 2019 - 2024. All rights reserved.