gpt4 book ai didi

android - MVVMCross 是否有办法在单击 ListView 上的 ImageButton 时更改选择器?

转载 作者:行者123 更新时间:2023-11-29 02:00:51 31 4
gpt4 key购买 nike

问题和没有用MVVMCross编程一样,但我想知道有没有“跨平台”的解决方案:

当在 MvxBindableListView(或 ListView)上使用 ImageButton 时,我们必须添加一些选项才能在此按钮上使用操作:

        <ImageButton
...
android:focusable="false"
android:clickable="true"
...
local:MvxBind="'Click':{'Path':'Command1'}}"
/>

使用这些参数,按钮对“Command1”使用react。但问题是 ListView 的“可视选择器”没有改变。

举个例子:

当您的 ListView 中有 5 行并且第一行被选中时。我触摸第 3 行的 ImageButton,“Command1”将使用react(使用 ListView 的第 3 项),但选择器将留在第一行。

因此,在 Android 中,我们必须像这样放置一些代码:

_imagebutton.Click += (object sender, EventArgs eventsArgs) =>
{
View v = ...
MvxBindableListView l = ...
int p = l.GetPositionForView(...);
l.PerformItemClick(..., p, p);
};

使用这段代码,可以选择正确的项目并且行为是正确的(只要我不想使用 ItemClick 触发真实事件)。但是这个解决方案是“Android 方式”而不是真正的跨平台(我让你想象初始化所有这些东西的可怕代码)

有人有更好的解决方案吗?

雨果

最佳答案

部分地,这感觉就像这只是“UI 视觉糖果”——因此属于“View concern”的范畴——因此它不是 mvvmcross 通常尝试制作跨平台的东西。

不过……我觉得还是有办法的。

如果 ViewModel 中的命令处理程序还在 ViewModel 上设置了一个 CurrentSelectedPosition 整数,那么每个 UI 都可以将 ViewModel 中的 SelectedItemPosition 绑定(bind)到每个 UI 中的每个列表 - 这应该会导致 UI native 更新选择。

我认为这可行...但在 Android 上它需要一些绑定(bind):

public class MvxAdapterViewSelectedItemPositionTargetB-inging : MvxBaseAndroidTargetBinding
{
private readonly AdapterView _adapterView;

public MvxAdapterViewSelectedItemPositionTargetBinging(AdapterView adapterView)
{
_adapterView = adapterView;
_adapterView.ItemSelected += AdapterViewOnItemSelected;
}

public override void SetValue(object value)
{
_adapterView.SetSelection((int)value);
}

private void AdapterViewOnItemSelected(object sender, AdapterView.ItemSelectedEventArgs itemSelectedEventArgs)
{
FireValueChanged(itemSelectedEventArgs.Position);
}

public override MvxBindingMode DefaultMode
{
get
{
return MvxBindingMode.TwoWay;
}
}

public override Type TargetType
{
get
{
return typeof(Int32);
}
}

protected override void Dispose(bool isDisposing)
{
if (isDisposing)
{
if (_adapterView != null)
{
_adapterView.ItemSelected -= AdapterViewOnItemSelected;
}
}
base.Dispose(isDisposing);
}
}

注册使用:

        registry.RegisterFactory(new MvxCustomBindingFactory<AdapterView>("SelectedItemPosition", adapterView => new MvxAdapterViewSelectedItemPositionTargetBinging(adapterView)));

并绑定(bind)到 axml 中的 UI,例如作为:

<Mvx.MvxBindableListView
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
local:MvxBind="{'ItemsSource':{'Path':'Emails'},'SelectedItemPosition':{'Path':'CurrentSelectedPosition'}}"
local:MvxItemTemplate="@layout/listitem_email"
/>

我使用电子邮件列表测试了这个想法,其中 ViewModel 列表项是:

    public class SimpleEmail
{
public EmailViewModel Parent { get; set; }
public string From { get; set; }
public string Header { get; set; }
public string Message { get; set; }
public ICommand Command1
{
get
{
return new MvxRelayCommand(() => Parent.CurrentSelectedPosition = Parent.Emails.IndexOf(this));
}
}
}
  • 但这显然只是一个演示...

注意:我在上面的代码中使用的是选定位置而不是选定对象 - 因为我知道您使用的列表很长!


如果您想对纯 Android 代码考虑一种不同的方法,那么我认为您可以通过继承 Mvx.MvxBindableListView(也可能是列表项)并使用这些类以可能的方式更新选择来做到这一点不那么痛苦的方式。

关于android - MVVMCross 是否有办法在单击 ListView 上的 ImageButton 时更改选择器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12738516/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com