首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MvxBind CheckedChange SwitchCompat

MvxBind CheckedChange SwitchCompat
EN

Stack Overflow用户
提问于 2016-12-21 09:37:31
回答 2查看 941关注 0票数 2

我在将我的Android.Support.V7.Widget.SwitchCompat绑定到我的视图模型(Mvvmcross是我正在使用的框架)时遇到了麻烦,我对另一个对象的点击绑定做得非常好。

查看视图时遇到的错误如下:

代码语言:javascript
复制
12-21 10:32:06.459 I/MvxBind (22969):  42,82 Failed to create target binding for binding CheckedChange for OnCheckedChanged
[0:] MvxBind:Warning: 42,82 Failed to create target binding for binding CheckedChange for OnCheckedChanged

对于我的开关数量,我做了多次。

他们说,它可能必须做一些与链接器,不包括东西,因为反射魔法。

通过这种方式,他们说您必须创建一个文件"LinkerPleaseInclude“来保持对您的开关计算机的引用。我这样做了,但仍然存在错误。

LinkerPleaseInclude

代码语言:javascript
复制
class LinkerPleaseInclude
{
    public void Include(TextView text)
    {
        text.AfterTextChanged += (sender, args) => text.Text = "" + text.Text;
        text.Hint = "" + text.Hint;
    }

    public void Include(CompoundButton cb)
    {
        cb.CheckedChange += (sender, args) => cb.Checked = !cb.Checked;
        cb.Hint = "" + cb.Hint;
    }
    public void Include(SwitchCompat cb)
    {
        cb.CheckedChange += (sender, args) => cb.Checked = !cb.Checked;
        cb.Hint = "" + cb.Hint;
    }
    public void Include(ICommand command)
    {
        command.CanExecuteChanged += (s, e) => { if (command.CanExecute(null)) command.Execute(null); };
    }
    public void Include(CheckBox checkBox)
    {
        checkBox.CheckedChange += (sender, args) => checkBox.Checked = !checkBox.Checked;
    }
}

我的ViewLayout:

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:local="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="@dimen/md_list_single_line_item_height"
    android:gravity="center_vertical"
    android:paddingLeft="@dimen/md_list_item_horizontal_edges_padding"
    android:paddingRight="@dimen/md_list_item_horizontal_edges_padding">
  <android.support.v7.widget.SwitchCompat
    android:id="@+id/mySwitch"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:layout_centerVertical="true"
    local:MvxBind="Checked IsActive; Click OnSwitchClick; CheckedChange OnCheckedChanged" />
  <TextView
    android:id="@+id/Name"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:textColor="@color/md_text_dark_primary_87"
    android:textSize="@dimen/md_list_item_primary_text"
    local:MvxBind="Text Name"/>
  <TextView
    android:id="@+id/Kind"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_alignParentLeft="true"
    android:textColor="@color/md_text_dark_secondary_54"
    android:textSize="@dimen/md_list_item_secondary_text"
    android:layout_below="@+id/Name"
    local:MvxBind="Text Kind"/>
</RelativeLayout>

此布局是另一个布局的子程序:

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:local="http://schemas.android.com/apk/res-auto"
  android:orientation="vertical"
  android:layout_width="match_parent"
  android:layout_height="@dimen/md_list_two_line_item_height"
  android:paddingTop="?android:attr/actionBarSize"
  android:fitsSystemWindows="true">
  <MvxClickableLinearLayout
      android:id="@+id/animalSelectionsList"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:orientation="vertical"
      android:divider="@drawable/divider_horizontal"
      android:showDividers="middle"
      local:MvxBind="ItemsSource SelectionsList"
      local:MvxItemTemplate="@layout/listitem_animal_selections" />
</LinearLayout>
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-12-21 16:59:39

CheckedChange是一个事件,因此它不是一个公共属性。您不能在MvvmCross中直接绑定事件,除非您创建自己的目标绑定来处理此问题并公开命令。

这可能看起来像:

代码语言:javascript
复制
public class MvxCompoundButtonCheckedChangeBinding : MvxAndroidTargetBinding
{
    private ICommand _command;
    private IDisposable _checkedChangeSubscription;
    private IDisposable _canExecuteSubscription;
    private readonly EventHandler<EventArgs> _canExecuteEventHandler;

    protected CompoundButton View => (CompoundButton)Target;

    public MvxCompoundButtonCheckedChangeBinding(CompoundButton view)
        : base(view)
    {
        _canExecuteEventHandler = OnCanExecuteChanged;
        _checkedChangeSubscription = view.WeakSubscribe<CompoundButton, CompoundButton.CheckedChangeEventArgs>(nameof(view.CheckedChange), ViewOnCheckedChangeClick);
    }

    private void ViewOnCheckedChangeClick(object sender, CompoundButton.CheckedChangeEventArgs args)
    {
        if (_command == null)
            return;

        if (!_command.CanExecute(null))
            return;

        _command.Execute(view.Checked);
    }

    protected override void SetValueImpl(object target, object value)
    {
        _canExecuteSubscription?.Dispose();
        _canExecuteSubscription = null;

        _command = value as ICommand;
        if (_command != null)
        {
            _canExecuteSubscription = _command.WeakSubscribe(_canExecuteEventHandler);
        }
        RefreshEnabledState();
    }

    private void RefreshEnabledState()
    {
        var view = View;
        if (view == null)
            return;

        var shouldBeEnabled = false;
        if (_command != null)
        {
            shouldBeEnabled = _command.CanExecute(null);
        }
        view.Enabled = shouldBeEnabled;
    }

    private void OnCanExecuteChanged(object sender, EventArgs e)
    {
        RefreshEnabledState();
    }

    public override MvxBindingMode DefaultMode => MvxBindingMode.OneWay;

    public override Type TargetType => typeof(ICommand);

    protected override void Dispose(bool isDisposing)
    {
        if (isDisposing)
        {
            _checkedChangeSubscription?.Dispose();
            _checkedChangeSubscription = null;

            _canExecuteSubscription?.Dispose();
            _canExecuteSubscription = null;
        }
        base.Dispose(isDisposing);
    }
}

然后,您需要在Setup.cs中以FillTargetFactories覆盖方式注册它:

代码语言:javascript
复制
registry.RegisterCustomBindingFactory<View>("MyCheckedChange", 
    view => new MvxCompoundButtonCheckedChangeBinding(view));

然后,可以将MyCheckedChange绑定到命令。

票数 4
EN

Stack Overflow用户

发布于 2020-09-20 01:11:40

我只将CompoundButton替换为SwitchCompat,因此它现在可以工作(并重新命名为类):

代码语言:javascript
复制
public class MvxButtonCheckedChangeBinding : MvxAndroidTargetBinding
{
    private ICommand _command;
    private IDisposable _checkedChangeSubscription;
    private IDisposable _canExecuteSubscription;
    private readonly EventHandler<EventArgs> _canExecuteEventHandler;

    public static string Name = "MyCheckedChange";

    protected CompoundButton View => (SwitchCompat)Target;

    public MvxButtonCheckedChangeBinding(SwitchCompat view)
        : base(view)
    {
        _canExecuteEventHandler = OnCanExecuteChanged;
        _checkedChangeSubscription = view.WeakSubscribe<SwitchCompat, SwitchCompat.CheckedChangeEventArgs>(nameof(view.CheckedChange), ViewOnCheckedChangeClick);
    }

    private void ViewOnCheckedChangeClick(object sender, SwitchCompat.CheckedChangeEventArgs args)
    {
        var view = (SwitchCompat)sender;

        if (view == null || _command == null)
            return;

        if (!_command.CanExecute(null))
            return;

        _command.Execute(view.Checked);
    }

    protected override void SetValueImpl(object target, object value)
    {
        _canExecuteSubscription?.Dispose();
        _canExecuteSubscription = null;

        _command = value as ICommand;
        if (_command != null)
        {
            _canExecuteSubscription = _command.WeakSubscribe(_canExecuteEventHandler);
        }
        RefreshEnabledState();
    }

    private void RefreshEnabledState()
    {
        var view = View;
        if (view == null)
            return;

        var shouldBeEnabled = false;
        if (_command != null)
        {
            shouldBeEnabled = _command.CanExecute(null);
        }
        view.Enabled = shouldBeEnabled;
    }

    private void OnCanExecuteChanged(object sender, EventArgs e)
    {
        RefreshEnabledState();
    }

    public override MvxBindingMode DefaultMode => MvxBindingMode.OneWay;

    public override Type TargetType => typeof(ICommand);

    protected override void Dispose(bool isDisposing)
    {
        if (isDisposing)
        {
            _checkedChangeSubscription?.Dispose();
            _checkedChangeSubscription = null;

            _canExecuteSubscription?.Dispose();
            _canExecuteSubscription = null;
        }
        base.Dispose(isDisposing);
    }
}

当然,不要忘记在安装类中注册它,正如Cheesebaron在上面所写的

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41259474

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档