这个问题是关于两个MAUI控件(开关
和列表视图
)-我在同一个问题中询问这两个控件,因为我希望这两个控件的问题根源是相同的。但完全有可能它们是不同的问题,只是有一些共同的症状。(CollectionView
也有类似的问题,但其他混杂因素使演示变得更加困难。)
我在我的MAUI应用程序中使用双向数据绑定:对数据的更改可以直接来自用户,也可以来自后台轮询任务,该任务检查规范数据是否已在其他地方更改。我面临的问题是,视图模型的更改不会以可视方式传播到Switch。IsTokgled
和ListView。选择项目
属性,即使控件确实引发事件,表明它们已经“注意到”属性更改。其他控件(例如Label
和Checkbox
)会以可视方式更新,表明视图模型通知工作正常,UI本身总体上是健康的。
构建环境:Visual Studio2022 17.2.0预览版2.1
应用程序环境:Android,模拟器像素5-API 30或真正的像素6
下面是示例代码,但最基本的问题是,这是否是代码中的某个错误(我是否需要“告诉”控件出于某种原因进行自我更新?)或者可能是毛伊岛的一个虫子(在这种情况下,我应该报告它)?
下面的示例代码可以直接添加到“文件新项目”MAUI应用程序(名称为“MauiPlayground”,以使用相同的命名空间),或者都可以从我的演示代码存储库中获得。每个示例都是独立的——您可以只尝试一个。(然后更新App.cs
以将Main Page
设置为正确的示例。)
这两个例子都有一个非常简单的情况:一个双向绑定到视图模型的控件,以及一个更新视图模型属性的按钮(以模拟真实应用程序中“数据已在其他地方修改”)。在这两种情况下,控件在视觉上保持不变。
请注意,我在这两种情况下都指定了{Binding…,Mode=TwoWay}
,尽管这是这些属性的默认值,只是为了非常清楚这不是问题所在。
ViewModelBase
代码由两个示例共享,它只是一种方便的方式,可以引发INotifyPropertyChanged。PropertyChanged
没有任何额外的依赖项:
ViewModelBase。反恐精英:
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace MauiPlayground;
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public bool SetProperty<T>(ref T field, T value, [CallerMemberName] string name = null)
{
if (EqualityComparer<T>.Default.Equals(field, value))
{
return false;
}
field = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
return true;
}
}
开关emo.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiPlayground.SwitchDemo">
<StackLayout>
<Label Text="Switch binding demo" />
<HorizontalStackLayout>
<Switch x:Name="switchControl"
IsToggled="{Binding Toggled, Mode=TwoWay}"
Toggled="Toggled" />
<CheckBox IsChecked="{Binding Toggled, Mode=TwoWay}" />
<Label Text="{Binding Toggled}" />
</HorizontalStackLayout>
<Button Text="Toggle" Clicked="Toggle" />
<Label x:Name="manualLabel1" Text="Value set in button click handler" />
<Label x:Name="manualLabel2" Text="Value set in toggled handler" />
</StackLayout>
</ContentPage>
切换演示。反恐精英
namespace MauiPlayground;
public partial class SwitchDemo : ContentPage
{
public SwitchDemo()
{
InitializeComponent();
BindingContext = new ViewModel();
}
private void Toggle(object sender, EventArgs e)
{
var vm = (ViewModel)BindingContext;
vm.Toggled = !vm.Toggled;
manualLabel1.Text = $"Set in click handler: {switchControl.IsToggled}";
}
private void Toggled(object sender, ToggledEventArgs e) =>
manualLabel2.Text = $"Set in toggled handler: {switchControl.IsToggled}";
private class ViewModel : ViewModelBase
{
private bool toggled;
public bool Toggled
{
get => toggled;
set => SetProperty(ref toggled, value);
}
}
}
点击“切换”按钮后模拟器的屏幕截图,该按钮更新视图模型:
注意事项:
直接单击Switch
控件确实会在视觉上切换它。
listViewDemo.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiPlayground.ListViewDemo">
<StackLayout>
<Label Text="ListView binding demo" />
<ListView x:Name="listView" ItemsSource="{Binding Items}"
SelectedItem="{Binding SelectedItem, Mode=TwoWay}"
VerticalOptions="Start"
ItemSelected="ItemSelected"/>
<Label Text="{Binding SelectedItem}" />
<Button Text="Toggle" Clicked="Toggle" />
<Label x:Name="manualLabel1" Text="Text set in button click handler" />
<Label x:Name="manualLabel2" Text="Text set in item selected handler" />
</StackLayout>
</ContentPage>
ListViewDemo。反恐精英
namespace MauiPlayground;
public partial class ListViewDemo : ContentPage
{
public ListViewDemo()
{
InitializeComponent();
BindingContext = new ViewModel();
}
private void Toggle(object sender, EventArgs e)
{
var vm = (ViewModel)BindingContext;
vm.SelectedItem = vm.SelectedItem == "First" ? "Second" : "First";
manualLabel1.Text = $"Set in click handler: {listView.SelectedItem}";
}
private void ItemSelected(object sender, EventArgs e) =>
manualLabel2.Text = $"Set in item selected handler: {listView.SelectedItem}";
private class ViewModel : ViewModelBase
{
public List<string> Items { get; } = new List<string> { "First", "Second" };
private string selectedItem = "First";
public string SelectedItem
{
get => selectedItem;
set => SetProperty(ref selectedItem, value);
}
}
}
点击“切换”按钮后模拟器的屏幕截图,该按钮更新视图模型:
注意事项:
列表视图
本身似乎没有选定的项目有趣的是,列表视图确实会改变外观:在单击按钮之前,第一个项目被可视化地选中(橙色)。从列表中手动选择一个项目会更新所有属性,但我们看不到橙色的选定项目。
这两个可能都是毛伊岛目前发布的版本中的漏洞。
此错误最近发布,交换机已经有了解决此问题的修复程序。
开关的问题。IsToggled
已知并已修复,但在下一个RC发布(6.0.300-RC.1)之前将不可用。
我没有发现任何有关ListView
问题的报告问题,但我能够重现它。这似乎是由为每个项目创建的默认ViewCell
造成的。可以通过指定自定义的列表视图来修复它。ItemTemplate
如下所示:
<ListView x:Name="listView" ItemsSource="{Binding Items}"
SelectedItem="{Binding SelectedItem, Mode=TwoWay}"
VerticalOptions="Start"
ItemSelected="ItemSelected">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Label Text="{Binding}" />
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
问题内容: 我有一个简单的Bean,它具有彼此相关的某些属性。例如,此bean具有一个名为 discountRate 的属性和另一个名为 DiscountValue 的属性。DiscountRate是应用于销售的折扣百分比(%)。discountValue是应用于销售的折扣值($)。由于用户可以告知百分比或值,而且我需要将两个值存储在数据库中,因此JavaFX双向绑定可以解决此问题,但是,正如您可
初始值设置为true后,我与切换按钮的双向绑定将被分离。当我取消按钮时,它不再绑定。 我有两个切换按钮: 我希望绑定到的BackupViewModel(实例为BackupVM)中的我的属性: 当一个被切换时,我会显示一个特定的用户控件(视图)并隐藏另一个。我需要做的是告诉我的底层视图模型视图是隐藏的,这样我就可以停止刷新一些数据的计时器。加载IsChecked值后,由于某种原因绑定会被分离。以下是
本文向大家介绍什么是双向绑定?原理是什么?相关面试题,主要包含被问及什么是双向绑定?原理是什么?时的应答技巧和注意事项,需要的朋友参考一下 双向数据绑定个人理解就是存在data→view,view→data两条数据流的模式。其实可以简单的理解为change和bind的结合。目前双向数据绑定都是基于Object.defineProperty()重新定义get和set方法实现的。修改触发set方法赋值
问题内容: 给一个非常基础的类(将导入解析为javafx包): 某些字段表示在.fxml文件中定义的控件: 以及最基本使用属性包装器的数据模型: 我尝试将ui控件与Initialize中的数据模型绑定: 但是这样做, 我得到了不可编辑的控件 。注释掉Bindings.bindBidirectional行后,该控件通常可以编辑,并且可以通过text01字段访问其值。 此装订单中缺少的成分是什么? 问
react中的双向绑定和vue中双向绑定是一回事吗? react中的双向绑定我只在表单上看到。 vue中的双向绑定(v-model)我感觉它是同步父子组件上的两个可响应数据(这么做的原因应该是希望在子组件上改变时,父组件也跟着改变。)。
Mpx针对表单组件提供了wx:model双向绑定指令,类似于v-model,该指令是一个语法糖指令,监听了组件抛出的输入事件并对绑定的数据进行更新,默认情况下会监听表单组件的input事件,并将event.detail.value中的数据更新到组件的value属性上。 简单实用示例如下: <view> <input type="text" wx:model="{{message}}"> <