2016-12-21 34 views
1

我遇到了將我的Android.Support.V7.Widget.SwitchCompat綁定到我的視圖模型(Mvvmcross是我正在使用的框架)的問題 我的確和使用另一個對象上的點擊綁定完全相同,它工作得很好。MvxBind CheckedChange SwitchCompat

觀看視圖時,我發現了錯誤是如下:

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」以保存對你的switchcompat的引用。我是這樣做的,但仍然錯誤依然存在。

LinkerPleaseInclude

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:

<?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> 

這種佈局的另一個佈局的孩子:

<?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> 
+0

Iam不確定,但也許是因爲android.support.v7.widget.SwitchCompat與複選框無關?它只是不支持CheckedChange? https://developer.android.com/reference/android/support/v7/widget/SwitchCompat.html – Cyriac

+0

SwitchCompat是CompoundButton的派生類型。就像Checkbox一樣。 https://developer.android.com/reference/android/widget/CompoundButton.OnCheckedChangeListener.html CompoundButton有一個事件'CheckedChange' – Baklap4

+0

只能問那麼看看你的模型。對於鏈接器的東西,嘗試以不同的方式設置項目設置中的android選項,以便鏈接器爲sdk和用戶程序集執行鏈接或不鏈接(不知道atm中的默認設置是什麼)。只是爲了測試它是否是連接器故障。 – Cyriac

回答

2

CheckedChange是一個事件,所以它不是一個公共財產。您不能直接在MvvmCross中綁定事件,除非您創建自己的目標綁定來處理此事件並公開命令。

這可能看起來像:

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); 
    } 
} 

然後,你需要在FillTargetFactories覆蓋註冊在你Setup.cs:

registry.RegisterCustomBindingFactory<View>("MyCheckedChange", 
    view => new MvxCompoundButtonCheckedChangeBinding(view)); 

然後,你可以綁定MyCheckedChange你的命令。

+0

那麼這個類是什麼https://github.com/MvvmCross/MvvmCross/blob/develop/MvvmCross/Binding/Droid/Target/MvxCompoundButtonCheckedTargetBinding.cs? – Cyriac

+0

這個工作原理可疑!但作爲@Cyriac提到什麼是其他類? – Baklap4

+1

那一個是你已經使用的「Checked」來源。 – Cheesebaron

相關問題