c# - 使用具有两个视图的 mvvm?
问题描述
我有一个关于绑定的问题。我尝试在 fody.propertychanged 的帮助下将我的第二个视图绑定到一个空应用程序中的 Viewmodel,因为我在我的项目中做了它,但它没有工作。
所以,我做了一个干净的石板并重试,但这仍然不起作用。我不知道为什么它不起作用;这是我到目前为止所尝试的。
基础视图模型
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using PropertyChanged;
namespace TestApp
{
[AddINotifyPropertyChangedInterface]
public class BaseViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void SetProperty<T>(ref T storage, T value, string propertyName)
{
storage = value;
RaisePropertyChangedEvent(propertyName);
}
protected void RaisePropertyChangedEvent(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
浏览视图模型
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Input;
using System.Threading;
using System.Threading.Tasks;
using System.Configuration;
using System.Collections.Specialized;
using System.IO;
namespace TestApp
{
public class BrowseViewModel : BaseViewModel
{
#region public variables
private string _webUrl;
public string WebUrl
{
get => _webUrl;
set
{
//This will change based on how you have implemented your BaseViewModel!
//The method name might be different, or have different parameters!
this.SetProperty(ref _webUrl, value, nameof(WebUrl));
//Call the save file path validation method...
SaveFilePath();
}
}
private string _errorMessage;
public string ErrorMessage
{
get => _errorMessage;
private set
{
//This will change based on how you have implemented your BaseViewModel!
//This method should call NotifyPropertyChange to notify the UI to update...
this.SetProperty(ref _errorMessage, value, nameof(ErrorMessage));
}
}
#endregion
#region Public Commands
public ICommand SaveCommand { get; set; }
#endregion
#region Constructor
public BrowseViewModel()
{
this.SaveCommand = new RelayCommand(SaveFilePath);
}
#endregion
#region Private methods
private void SaveFilePath()
{
if (File.Exists(_webUrl))
{
_errorMessage = "String works";
}
else
{
_errorMessage = "Filen existerar ej";
}
}
#endregion
}
}
主窗口.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace TestApp
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
BrowseWindow browse = new BrowseWindow();
browse.Show();
browse.DataContext = new BrowseViewModel();
InitializeComponent();
}
}
}
浏览窗口.xaml
<Window x:Class="TestApp.BrowseWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:TestApp"
mc:Ignorable="d"
Title="BrowseWindow" Height="450" Width="800">
<Grid>
<Label Content="{Binding errorMessage}" HorizontalAlignment="Left" Margin="10,383,0,0" VerticalAlignment="Top" />
<Button Content="Button" HorizontalAlignment="Left" Margin="684,368,0,0" VerticalAlignment="Top" Width="75" Command="{Binding SaveCommand}"/>
</Grid>
</Window>
浏览窗口
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace TestApp
{
/// <summary>
/// Interaction logic for BrowseWindow.xaml
/// </summary>
public partial class BrowseWindow : Window
{
public BrowseWindow()
{
InitializeComponent();
this.DataContext = new BrowseViewModel();
}
}
}
中继命令
using System;
using System.Windows.Input;
namespace TestApp
{
public class RelayCommand : ICommand
{
#region Public events
/// <summary>
/// Eventet som används när <see cref="CanExecute(object)"/> värdet har ändrats
/// </summary>
public event EventHandler CanExecuteChanged = (sender, e) => { };
#endregion
#region Private members
private Action mAction;
#endregion
#region Constructor
/// <summary>
/// Standard Konstruktor
/// </summary>
public RelayCommand(Action action)
{
mAction = action;
}
#endregion
#region Command Methods
/// <summary>
/// Ett action Kommando kan alltid köras
/// </summary>
/// <param name="parameter"></param>
/// <returns></returns>
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
mAction();
}
#endregion
};
}
解决方案
当您更改私有字段的值时,_errorMessage
您可以解决该属性设置器ErrorMessage
将通知该属性更改。
您必须将新值分配给属性本身才能让设置器代码进入游戏。
private void SaveFilePath()
{
if (File.Exists(_webUrl))
{
ErrorMessage = "String works";
}
else
{
ErrorMessage = "Filen existerar ej";
}
}
更新
我刚刚在您的 XAML 中看到另一个绑定错误
<Label Content="{Binding errorMessage}" .../>
但它区分大小写,因此您必须使用正确的名称,而不是某些名称
<Label Content="{Binding ErrorMessage}" .../>
在调试时,您应该始终检查输出窗口是否存在绑定错误。
推荐阅读
- ubuntu - 如何使用身份验证设置本地代理以进行测试
- nginx - 简化静态资产的 Grunt 压缩
- python - 在 3D 中计算简单对象的运动
- cakebuild - 使用 Cake Build (C# Make) 将提交推送到 Azure Repo
- reactjs - 同时使用 firebase-admin 和 pyrebase
- c - 使用链表打印真值表的 C 语言程序
- node.js - Rejected Promise 打破循环,尽管 catch
- css - SPIFFS Upload Failed Error Code -10010 将文件上传到 ESP8266 时
- oracle - 如何在 Oracle DB 18c XE 中删除并重新创建可插拔数据库?
- wordpress - 如何在WordPress中使用插件制作粘性标题