- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
对于这个冗长的问题,我深表歉意,但我希望你能坚持下去。我已尽力包含所有相关代码片段,以便准确解释我想要实现的目标。
我正在尝试将我的移动应用程序转换为 MVVM 设计模式,但我在根据模型中发生的更改更新 View 时遇到了一些困难。
我已将我的应用程序拆分为经典的模型、 View 、 View 模型结构。
目前,我正在尝试从我的模型 SoundScapeData.cs
传播数据我的观点HomePage.xaml
.
我的 HomePage.xaml
代码隐藏文件如下所示:
namespace AX2018
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class HomePage : ContentPage
{
public HomePage()
{
InitializeComponent();
BindingContext = new HomePageViewModel();
}
private void OnConnectButtonClicked(object sender, EventArgs e)
{
Bluetooth bluetooth = new Bluetooth();
bluetooth.Connect();
}
}
}
如您所见,我使用 BindingContext
绑定(bind)我的数据关键字并将其绑定(bind)到 HomePageViewModel
的新实例类。
我正在连接蓝牙设备,因此调用 bluetooth.Connect()
在点击 Button
时调用在HomePage.xaml
看法。然后,此蓝牙设备使用特定值更新应用程序。
我想强调的是,蓝牙连接运行良好,并且已经过验证可以在转换为 MVVM 设计模式之前与 View 一起工作。
我的 ViewModel,HomePageViewModel.cs
,看起来像这样:
namespace AX2018
{
public class HomePageViewModel
{
private SoundScapeData _soundScapeData;
public SoundScapeData SoundScapedata { get { return _soundScapeData; } }
public HomePageViewModel()
{
_soundScapeData = new SoundScapeData();
}
}
}
附带说明一下,我对如何设计 View 模型有点困惑,因为模型 SoundScapeData.cs
目前就是这么简单。这个中间 View 模型是否必要?
这是我的 SoundScapeData.cs
型号:
namespace AX2018
{
public class SoundScapeData : INotifyPropertyChanged
{
private double _spl;
public double SPL
{
get { return _spl; }
set
{
_spl = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
从模型中可以看出,它实现了 INotifyPropertyChanged
接口(interface),并在方法OnPropertyChanged()
中有处理事件的相关函数.
我的看法,HomePage.xaml
, 相当冗长 - 它由一个 9 x 3 网格组成,标签放置在特定位置。这些标签应反射(reflect) SoundScapeData.cs
中的值模型(和其他模型,但那是在路上)。以下是相关片段:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:AX2018"
x:Class="AX2018.HomePage">
<ContentPage.BindingContext>
<local:HomePageViewModel/>
</ContentPage.BindingContext>
...
<Label Text="{Binding SoundScapedata.SPL}"
FontSize="68" Style="{StaticResource ColoredLabel}"
Grid.Row="4"
Grid.Column="1"
Margin="-20"></Label>
如您所见,我已经在 View 中绑定(bind)了数据HomePage.xaml
查看模型 HomePageViewModel.cs
,其中包含 SoundScapeData.cs
的一个实例模型,它又实现了 INotifyPropertyChanged
界面。
据我了解,这是使用 MVVM 设计模式时数据绑定(bind)方面的正确方法。然而,SPL 的变化并没有反射(reflect)在我的 View 中 HomePage.xaml
.
我在一个单独的类中更新 SPL 值,Bluetooth.cs
, 它继承自 SoundScapeData.cs
模型。这是 Connect()
的片段来自 Bluetooth
的方法类:
namespace AX2018
{
public async void Connect()
{
public class Bluetooth : SoundScapeData
...
var dbValue = (double)BitConverter.ToUInt16(temp1, 0) / 256 * 48;
SPL = dbValue;
...
}
}
再次,对于这个相当长的问题,我深表歉意,但我希望有人能指出我做错了什么。我想重申,转换为 MVVM 之前 View 中的 SPL 值确实更新了,所以我的数据绑定(bind)肯定有问题。
提前谢谢你,
汉森
最佳答案
我会在这里回答,因为评论太短无法解释。如果我拼错了一些名字,请原谅:P让我们总结一下您的场景:
现在:
主页(查看)
我真的不知道在 Xamarin oyu 中是否必须复制它,请记住您在后面的代码中设置了它。
<ContentPage.BindingContext>
<local:HomePageViewModel/>
</ContentPage.BindingContext>
你也应该改变这个:
<Label Text="{Binding Spl}" <!--You dont need SoundScapeData anymore this is the public VM property -->
FontSize="68" Style="{StaticResource ColoredLabel}"
Grid.Row="4"
Grid.Column="1"
Margin="-20"></Label>
HomePageViewModel
它应该有你需要的尽可能多的属性。假设您的模型只有一个属性 SPL 。这就是您的模型,现在您必须通过 VM 将其放入 View 中。所以你的 VM 应该有一个属性(公共(public)/私有(private))来适应 View 和你的模型。
private string spl;
public string Spl
{
get {return this.spl;}
set
{
if (this.spl != value)
{
this.spl = value;
OnPropertyChanged("SPL);
}
当您单击该按钮并连接到蓝牙或它所做的任何操作时 (;P),因为它会更改模型,您必须更改您的 VM 属性。请记住,您的模型必须与 VM 中的实例相同。
所以...您应该附加到已更改的模型属性,以便更改您的 VM 属性,最好的方法是创建一个类(让我们尽可能多地应用 SOLID)
public class YourNewDataSource
{
#region Attributes
private readonly HomePageViewModel homePageViewModel;
#endregion
#region Public Methods
public YourNewDataSource(HomePageViewModel homePageViewModel)
{
this.homePageViewModel = homePageViewModel;
}
public void Initialize()
{
this.homePageViewModel.SoundScapeData.PropertyChanged += this.OnHomePageModelPropertyChanged;
}
#endregion
#region Event Handlers
private void OnHomePageModelPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
switch (e.PropertyName)
{
case "SPL":
this.homePageViewModel.Spl = this.homePageViewModel.SoundScapeData.Spl;
break;
}
}
#endregion
}
现在,当您启动您的应用程序或想要显示您的 View 时,您必须使用您的 VM 创建一个新的 YourNewDataSource:
public HomePage()
{
InitializeComponent();
HomePageViewModel homePageViewModel = new HomePageViewModel();
YourNewDataSource yourNewDataSource = new YourNewDataSource(homePageViewModel)
BindingContext = homePageViewModel;
}
看一看,试一试,问问你是否没有得到我刚刚写在这里的一些 s*** :D
我刚刚查看了您的 bluetooth.Connect 。
我不知道蓝牙类是否必须从 SoundScapeData 继承,但现在它不起作用,因为您在连接时会丢失 VM 的模型。如果您真的不需要从 SoundScapeData 继承,只需将一个参数添加到您的连接方法并将 Vm.SoundScapeData 传递给它即可。
关于c# - View 不会被模型更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50833147/
我在尝试从子文件夹调用 View 时遇到一些错误。首先,这东西能用 Route::get('/', function() { return View::make('sample'); }); 但是当我
我有另一个 View 设置,并准备好等待其viewmodel。我的RelayCommand到达我的“当前” View 模型。从当前的 View 模型显示新 View 的最佳方法是什么? 我一直在阅读,
我有一个 bigquery View ,我想与数据分析师共享,以便他们可以通过 Data Studio 访问其数据。此共享 View 对另一个数据集中的私有(private) View 进行查询,而私
我有 3 个 View ,并希望将它们集成到一个 View 中,以便它们成为这一 View 中的子文件夹。 我怎样才能做到这一点?还是我必须制作一个 View ,然后再次手动添加和配置这些 View
我在沙发数据库中有一些文档,这些文档的字段是不同关联文档的ID数组: { associatedAssets: ["4c67f6241f4a0efb7dc2abc24a004dfe", "270f
我正在开发一个小实用程序 View ,它将嵌入到我们的几个应用程序中。它将位于一个公共(public)图书馆中。 我应该将其作为 ViewModel 以及默认的 View 实现公开,还是作为具有固定
由于我的某些 View 具有相似的功能,因此我希望能够与每个 View 共享相同的 View 模型。我的想法是将 token 传递给viewmodel的构造函数,但这将导致代码中出现许多if和else
我有一个目标 View (蓝色 View 和红色 View 用于左上角位置)。我试图用手指移动这个 View 。如果 View 不旋转,一切都很好。 但当我旋转 View 并移动时,第一次就很好了。但
我收到这个错误, "Attempt to invoke virtual method 'android.view.View android.view.View.getRootView()' on a
我将发布我目前拥有的源代码,然后解释我的问题。 这是我希望过渡发生的窗口 这是关联的 View 模型 public class MainViewModel {
我正在尝试找出我遇到的错误。最初,我的同事只是使用 将 View 添加到 subview 中 [self.view addSubview:someController.view]; 来自当前ViewC
我是 MVVM 的新手,需要一些帮助。 我的应用程序由许多不同的窗口组成,这些窗口显示允许用户编辑业务层中的数据的控件。 目前,每次用户打开这些窗口之一的新实例时,都会从头开始创建一个 ViewMod
我一直在寻找与我类似的问题以找到解决方案,但我真的找不到类似的东西。 我试图使用 asynctask 类从解析中下载帖子数组,在获取帖子后,它应该在我的页面中设置帖子数组,并执行 setAdapter
这个问题在这里已经有了答案: What is local/remote and no-interface view in EJB? (2 个答案) 关闭 9 年前。 我以前理解它的意思是“接口(in
希望这不会太困惑。 我有一个主视图 Controller ( MainView ),在 View 底部有一个堆栈 View ,在堆栈 View 中我有三个 View 。在一个 View 中(我们称之为
我一直在想这个问题,我真的不知道如何正确地将一个 View Controller 管理的 View 添加到另一个 View Controller 的 View 中。 这不起作用,因为 View 没有完
在明显的情况下,我必须将大量文件从一个 View 复制到另一个 View 。要复制的文件名将作为输入给出。有什么想法可以通过脚本实现吗? 谢谢,日语 最佳答案 最简单的方法是使用 clearfsimp
我正在使用完整日历。这里我的问题是,当单击上一个按钮或下一个按钮单击功能时,如何找到月 View 、周 View 或日 View 格式的完整日历。这里正在调用下一个和上一个按钮的自定义代码。因为使用这
我对这两者感到困惑,并试图找出差异,但没有得到我正在寻找的特定内容。 在哪里使用索引 View 而不是普通 View 。 它们之间的一些重要区别。 最佳答案 关键的区别在于物化 View 很好,物化了
我在一个 xib 中有一个 CustomView,在两个不同的 xib 中有两个不同的 View 。我想在一个 CustomeView 中依次显示这两个 View 。我有一个 NSView 对象,它连
我是一名优秀的程序员,十分优秀!