Xamarin.android MVxRadioGroup SelectedIndexBinding
我从MvxRadioGroupSelectedItemBinding的源创建了一个RadioGroupSelectedIndexBindingXamarin.android MVxRadioGroup SelectedIndexBinding,xamarin.android,mvvmcross,Xamarin.android,Mvvmcross,我从MvxRadioGroupSelectedItemBinding的源创建了一个RadioGroupSelectedIndexBinding public class MvxRadioGroupSelectedIndexBinding : MvxAndroidTargetBinding { bool stopListeningCheckChanged = false; private int selectedIndex = -2; public int Selecte
public class MvxRadioGroupSelectedIndexBinding : MvxAndroidTargetBinding
{
bool stopListeningCheckChanged = false;
private int selectedIndex = -2;
public int SelectedIndex
{
get { return selectedIndex; }
set { if(value != selectedIndex) { selectedIndex = value; FireValueChanged(SelectedIndex); } }
}
public static void Register(IMvxTargetBindingFactoryRegistry registry)
{
registry.RegisterCustomBindingFactory<RadioGroup>("SelectedIndex", radioGroup => new MvxRadioGroupSelectedIndexBinding(radioGroup));
}
public MvxRadioGroupSelectedIndexBinding(RadioGroup radioGroup) : base(radioGroup)
{
if (radioGroup == null)
{
Mvx.Trace(MvxTraceLevel.Error, "RadioGroup SelectedIndex: radioGroup is null");
return;
}
radioGroup.CheckedChange += CheckedChange;
radioGroup.ChildViewAdded += RadioGroupOnChildViewAdded;
}
private void RadioGroupOnChildViewAdded(object sender, ViewGroup.ChildViewAddedEventArgs childViewAddedEventArgs)
{
var radioGroup = Target as RadioGroup;
if (selectedIndex == radioGroup.ChildCount-1)
{
stopListeningCheckChanged = true;
radioGroup.Check(radioGroup.GetChildAt(selectedIndex).Id);
stopListeningCheckChanged = false;
}
}
private void CheckedChange(object sender, RadioGroup.CheckedChangeEventArgs e)
{
if (stopListeningCheckChanged)
return;
var radioGroup = Target as RadioGroup;
var checkedId = e.CheckedId;
if (checkedId == View.NoId)
{
SelectedIndex = -1;
return;
}
for (var i = radioGroup.ChildCount - 1; i >= 0; i--)
{
if (checkedId == radioGroup.GetChildAt(i).Id)
{
SelectedIndex = i;
return;
}
}
SelectedIndex = -1;
Mvx.Trace(MvxTraceLevel.Error, "RadioGroup id not found: {0}", checkedId);
}
public override void SetValue(object index)
{
var radioGroup = Target as RadioGroup;
if (radioGroup == null)
return;
stopListeningCheckChanged = true;
selectedIndex = (int)index;
if (selectedIndex < 0 || selectedIndex >= radioGroup.ChildCount)
{
radioGroup.ClearCheck();
}
else
{
radioGroup.Check(radioGroup.GetChildAt(selectedIndex).Id);
}
stopListeningCheckChanged = false;
}
public override Type TargetType
{
get { return typeof(object); }
}
protected override void SetValueImpl(object target, object value)
{
}
public override MvxBindingMode DefaultMode
{
get { return MvxBindingMode.TwoWay; }
}
protected override void Dispose(bool isDisposing)
{
if (isDisposing)
{
var radioGroup = Target as RadioGroup;
if (radioGroup != null)
{
radioGroup.CheckedChange -= CheckedChange;
radioGroup.ChildViewAdded -= RadioGroupOnChildViewAdded;
}
}
base.Dispose(isDisposing);
}
}
它工作正常,但在viewmodel启动时不起作用:调用了从viewmodel到视图的绑定,但此时RadioGroup没有子视图。看起来他们还没有被充气
这是Mvvmcross定制充气机/绑定中的“错误”(或功能:p)?或者在MvxAndroidTargetBinding中有什么东西需要重载
编辑:MvxRadioGroupSelectedIndexBinding的代码(索引,而非项:不同于MvxRadioGroupSelectedItemBinding)
公共类MvxRadioGroupSelectedIndexBinding:MvxAndroidTargetBinding
{
bool stoplistingcheckchanged=false;
私有int selectedIndex=-2;
公共整数选择索引
{
获取{return selectedIndex;}
设置{if(value!=selectedIndex){selectedIndex=value;FireValueChanged(selectedIndex);}
}
公共静态无效寄存器(IMvxTargetBindingFactoryRegistry注册表)
{
registry.RegisterCustomBindingFactory(“SelectedIndex”,radioGroup=>new MVxRadioGroup SelectedIndexBinding(radioGroup));
}
公共MVX射线组SelectedIndexBinding(射线组射线组):基本(射线组)
{
如果(放射组==null)
{
跟踪(MvxTraceLevel.Error,“RadioGroup SelectedIndex:RadioGroup为空”);
返回;
}
radioGroup.CheckedChange+=CheckedChange;
radioGroup.ChildViewAdded+=RadioGroupOnChildViewEded;
}
private void RadioGroupOnChildViewed(对象发送者,ViewGroup.ChildViewAddedEventArgs ChildViewAddedEventArgs)
{
var radioGroup=目标为radioGroup;
如果(selectedIndex==radioGroup.ChildCount-1)
{
StopListengCheckChanged=true;
radioGroup.Check(radioGroup.GetChildAt(selectedIndex.Id));
StopListingCheckChanged=false;
}
}
私有void CheckedChange(对象发送方,RadioGroup.CheckedChangeEventArgs e)
{
如果(StopListingCheckChanged)
返回;
var radioGroup=目标为radioGroup;
var checkedId=e.checkedId;
if(checkedId==View.NoId)
{
SelectedIndex=-1;
返回;
}
对于(变量i=radioGroup.ChildCount-1;i>=0;i--)
{
if(checkedId==radioGroup.GetChildAt(i.Id)
{
SelectedIndex=i;
返回;
}
}
SelectedIndex=-1;
Trace(MvxTraceLevel.Error,“未找到放射组id:{0}”,checkedId);
}
公共覆盖无效集合值(对象索引)
{
var radioGroup=目标为radioGroup;
如果(放射组==null)
返回;
StopListengCheckChanged=true;
selectedIndex=(int)索引;
如果(selectedIndex<0 | | selectedIndex>=radioGroup.ChildCount)
{
radioGroup.ClearCheck();
}
其他的
{
radioGroup.Check(radioGroup.GetChildAt(selectedIndex.Id));
}
StopListingCheckChanged=false;
}
公共覆盖类型TargetType
{
获取{return typeof(object);}
}
受保护的覆盖无效SetValueImpl(对象目标,对象值)
{
}
公共覆盖MvxBindingMode默认模式
{
获取{return MvxBindingMode.TwoWay;}
}
受保护的覆盖无效处置(bool isDisposing)
{
if(isDisposing)
{
var radioGroup=目标为radioGroup;
如果(放射组!=null)
{
radioGroup.CheckedChange-=CheckedChange;
radioGroup.ChildViewAdded-=radioGroup ChildViewAdded;
}
}
基础处理(isDisposing);
}
}
用法
<RadioGroup
android:orientation="horizontal"
local:MvxBind="SelectedIndex SelectedChoiceIndex">
<RadioButton
android:text="choice 1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<RadioButton
android:text="choice 2"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RadioGroup>
“错误”是当调用SetValue时,RadioGroup没有子对象。我假设自定义充气器同时创建和绑定视图。事实上,只有当他们的孩子被夸大时,它才应该约束观点。我可能错了,我没有检查源代码。它还可能有其他不良副作用
这是Mvvmcross定制充气机/绑定中的“错误”(或功能:p)
两者都不是-我认为这完全超出了MvxRadioGroup
的设计目标范围
MVxRadioGroup SelectedItemBinding
是一个用户贡献,我相信它的设计目的就是要完全按照如下所示使用:
=>因此,它设计用于首先设置ItemsSource
的项目列表,然后再设置SelectedItem
我不相信MvxRadioGroup的作者有任何支持基于AXML的无线电选择列表的意图
话虽如此,如果有人想编写更广泛的RadioGroup解决方案-例如,可以处理AXML定义的列表,或者可以处理
ItemsSource
设置SelectedItem
后的更改,然后我认为这应该是完全可能做到的-看起来你已经朝着这个方向走了很长的路:)完美地处理所有动态和静态列表更改的组合,可能需要使用某种技术,每次添加itemsource
和/或静态项时都会重新检查SelectedItem
属性。出于实际原因,我认为这种重新检查需要在一些自定义的RadioGroup和/或基于绑定的代码中执行——我认为在XML膨胀处理程序中没有任何方法可以做到这一点,因为Android在膨胀期间根本不提供任何合适的ChildrenInflated和Added
类型回调
值得注意的是,XAML在这方面也面临着类似的挑战,例如,有关XAML组合框
场景,请参见,其中项目必须在所选项目之前设置。。我发现了一个wo
<MvxRadioGroup
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="40dp"
local:MvxItemTemplate="@layout/item_radio"
local:MvxBind="ItemsSource Items;SelectedItem SelectedItem"
/>