C# 这个组件的好处乍一看并不明显,它们是有效存在的,我将试着把它们卖给你:D
将ViewModel视为视图和模型之间的网关,其任务是通过对模型执行操作并将模型发送的结果返回给视图来服务来自视图(用户)的请求 如下所示:它承载这个加密示例的属性;将数据从视图传递到模型或从模型传递数据(由于WPF数据绑定而自动进行)。最后,它承载视图触发的命令C# 这个组件的好处乍一看并不明显,它们是有效存在的,我将试着把它们卖给你:D,c#,wpf,model-view-controller,mvvm,C#,Wpf,Model View Controller,Mvvm,将ViewModel视为视图和模型之间的网关,其任务是通过对模型执行操作并将模型发送的结果返回给视图来服务来自视图(用户)的请求 如下所示:它承载这个加密示例的属性;将数据从视图传递到模型或从模型传递数据(由于WPF数据绑定而自动进行)。最后,它承载视图触发的命令 public class EncryptorViewModel : ViewModelBase { private RelayCommand _cipher; private string _inputText;
public class EncryptorViewModel : ViewModelBase
{
private RelayCommand _cipher;
private string _inputText;
private string _outputText;
public EncryptorViewModel()
{
Model = new EncryptorModel();
}
private EncryptorModel Model { get; set; }
#region Public properties
public string InputText
{
get { return _inputText; }
set
{
_inputText = value;
RaisePropertyChanged();
Cipher.RaiseCanExecuteChanged();
}
}
public string OutputText
{
get { return _outputText; }
set
{
_outputText = value;
RaisePropertyChanged();
}
}
#endregion
#region Commands
public RelayCommand Cipher
{
get { return _cipher ?? (_cipher = new RelayCommand(CipherExecute, CipherCanExecute)); }
}
private void CipherExecute()
{
OutputText = Model.Cipher(InputText);
}
private bool CipherCanExecute()
{
return !string.IsNullOrWhiteSpace(InputText);
}
#endregion
}
视图:除了显示您的应用程序和调用ViewModel中的命令之外,没什么好说的
<Window x:Class="WpfApplication1.EncryptorView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wpfApplication1="clr-namespace:WpfApplication1"
Title="EncryptorView"
Width="165"
Height="188">
<Window.Resources>
<wpfApplication1:EncryptorViewModel x:Key="ViewModel" />
</Window.Resources>
<Grid DataContext="{Binding Source={StaticResource ViewModel}}">
<StackPanel>
<TextBlock Text="Input text" />
<TextBox Text="{Binding InputText, UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Text="Output text" />
<TextBox Text="{Binding OutputText}" />
<Button Command="{Binding Cipher}" Content="Cipher" />
</StackPanel>
</Grid>
</Window>
EncryptorViewModel1:
public class EncryptorViewModel1 : ViewModelBase
{
//private EncryptorModel Model { get; set; }
public EncryptorViewMode1l()
{
// Model = new EncryptorModel();
// Now you retrieve the model in App.xaml instead of declaring a private one above
var model =(EncryptorModel) Application.Current.FindResource("Model1");
}
}
场景:在同一视图中使用多个加密机
下面是另一个小示例,演示如何让用户在同一视图中选择加密方法
我们采用相同的视图模型
- 我们添加了
和AvailableEncryptors
属性CurrentEncryptor
- 我们修改了
,因此它考虑了CipherCanExecute
,用户只有在设置了CurrentEncryptor
并选择了加密机时才能加密InputText
- 另外,
也有一点变化,CipherExecute
根据指定的字符串和加密器进行加密EncryptorModel
public class EncryptorViewModel : ViewModelBase
{
private RelayCommand _cipher;
private IEncryptor _currentEncryptor;
private string _inputText;
private string _outputText;
public EncryptorViewModel()
{
Model = new EncryptorModel();
}
private EncryptorModel Model { get; set; }
public IEnumerable<IEncryptor> AvailableEncryptors
{
get
{
Type type = typeof (IEncryptor);
IEnumerable<IEncryptor> encryptors =
Assembly
.GetExecutingAssembly()
.GetTypes()
.Where(p => type.IsAssignableFrom(p) && !p.IsInterface && !p.IsAbstract)
.Select(s => (IEncryptor) Activator.CreateInstance(s));
return encryptors;
}
}
public IEncryptor CurrentEncryptor
{
get { return _currentEncryptor; }
set
{
_currentEncryptor = value;
RaisePropertyChanged();
Cipher.RaiseCanExecuteChanged();
}
}
#region Public properties
public string InputText
{
get { return _inputText; }
set
{
_inputText = value;
RaisePropertyChanged();
Cipher.RaiseCanExecuteChanged();
}
}
public string OutputText
{
get { return _outputText; }
set
{
_outputText = value;
RaisePropertyChanged();
}
}
#endregion
#region Commands
public RelayCommand Cipher
{
get { return _cipher ?? (_cipher = new RelayCommand(CipherExecute, CipherCanExecute)); }
}
private void CipherExecute()
{
OutputText = Model.Cipher(CurrentEncryptor, InputText);
}
private bool CipherCanExecute()
{
return CurrentEncryptor != null && !string.IsNullOrWhiteSpace(InputText);
}
#endregion
}
最后,我实现了加密机:
public interface IEncryptor
{
string Description { get; }
string Cipher(string text);
}
public class Encryptor1 : IEncryptor
{
#region IEncryptor Members
public string Description
{
get { return "Encryptor 1"; }
}
public string Cipher(string text)
{
char[] enumerable = text.Select(s => ++s).ToArray();
var cipher = new string(enumerable);
return cipher;
}
#endregion
}
public class Encryptor2 : IEncryptor
{
#region IEncryptor Members
public string Description
{
get { return "Encryptor 2"; }
}
public string Cipher(string text)
{
char[] enumerable = text.Select(s => --s).ToArray();
var cipher = new string(enumerable);
return cipher;
}
#endregion
}
以及更新后的视图:
<Window x:Class="WpfApplication1.EncryptorView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wpfApplication1="clr-namespace:WpfApplication1"
Title="EncryptorView"
Width="165"
Height="188">
<Window.Resources>
<wpfApplication1:EncryptorViewModel x:Key="ModelView" />
</Window.Resources>
<Grid DataContext="{Binding Source={StaticResource ModelView}}">
<StackPanel>
<TextBlock Text="Select an encryptor" />
<ComboBox ItemsSource="{Binding AvailableEncryptors}" SelectedItem="{Binding CurrentEncryptor}">
<ComboBox.ItemTemplate>
<DataTemplate DataType="wpfApplication1:IEncryptor">
<TextBlock Text="{Binding Description}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<TextBlock Text="Input text" />
<TextBox Text="{Binding InputText, UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Text="Output text" />
<TextBox Text="{Binding OutputText}" />
<Button Command="{Binding Cipher}" Content="Cipher" />
</StackPanel>
</Grid>
</Window>
结论
正如你所看到的,我在实现新类型方面做了一些努力,但这是值得的,每种加密方法都是独立的,加密机也是很好的。毕竟,加密机不是一种加密方法,所以最好将它们分开。您可以使用直接向上的WPF甚至控制台应用程序来实现。编辑问题,也许您可以将其移动到更合适的位置,例如?您可以使用直接向上的WPF甚至控制台应用程序来实现。编辑问题,也许你可以把它移到更合适的地方,比如?+1+如果我可以的话,请给我一个极好的、详细的、全面的答案,这也是正确的。没有MVVM意味着无论你谈论的是哪种类型的项目,WPF都会付出更多的努力。这是一个非常好的回答,我非常感谢你花时间回答这个问题!最后一个问题,如果没有数据返回到视图中,我只是在视图模型中没有属性吗?太好了,谢谢!是的,如果不想返回数据,则不要实现任何属性。正如你所看到的,有些人对你的问题不满意,想结束它。。。虽然这是一个很好的问题,但它确实应该重新制定,以适应现场;我会试着重新编排以保持开放。再次感谢您的帮助。您认为最好为每种字符串加密方法提供一个视图模型吗?请参阅我的编辑,我已经列出了一些您可能感兴趣的场景。+1+如果我可以的话,请给我一个极好的、详细的、全面的答案,这也是正确的。没有MVVM意味着无论你谈论的是哪种类型的项目,WPF都会付出更多的努力。这是一个非常好的回答,我非常感谢你花时间回答这个问题!最后一个问题,如果没有数据返回到视图中,我只是在视图模型中没有属性吗?太好了,谢谢!是的,如果不想返回数据,则不要实现任何属性。正如你所看到的,有些人对你的问题不满意,想结束它。。。虽然这是一个很好的问题,但它确实应该重新制定,以适应现场;我会试着重新编排以保持开放。再次感谢您的帮助。您认为最好为每种字符串加密方法都提供一个视图模型吗?请参阅我的编辑,我列出了一些您可能感兴趣的场景。
public class EncryptorModel
{
public string Cipher(IEncryptor encryptor, string text)
{
return encryptor.Cipher(text);
}
}
public interface IEncryptor
{
string Description { get; }
string Cipher(string text);
}
public class Encryptor1 : IEncryptor
{
#region IEncryptor Members
public string Description
{
get { return "Encryptor 1"; }
}
public string Cipher(string text)
{
char[] enumerable = text.Select(s => ++s).ToArray();
var cipher = new string(enumerable);
return cipher;
}
#endregion
}
public class Encryptor2 : IEncryptor
{
#region IEncryptor Members
public string Description
{
get { return "Encryptor 2"; }
}
public string Cipher(string text)
{
char[] enumerable = text.Select(s => --s).ToArray();
var cipher = new string(enumerable);
return cipher;
}
#endregion
}
<Window x:Class="WpfApplication1.EncryptorView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wpfApplication1="clr-namespace:WpfApplication1"
Title="EncryptorView"
Width="165"
Height="188">
<Window.Resources>
<wpfApplication1:EncryptorViewModel x:Key="ModelView" />
</Window.Resources>
<Grid DataContext="{Binding Source={StaticResource ModelView}}">
<StackPanel>
<TextBlock Text="Select an encryptor" />
<ComboBox ItemsSource="{Binding AvailableEncryptors}" SelectedItem="{Binding CurrentEncryptor}">
<ComboBox.ItemTemplate>
<DataTemplate DataType="wpfApplication1:IEncryptor">
<TextBlock Text="{Binding Description}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<TextBlock Text="Input text" />
<TextBox Text="{Binding InputText, UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Text="Output text" />
<TextBox Text="{Binding OutputText}" />
<Button Command="{Binding Cipher}" Content="Cipher" />
</StackPanel>
</Grid>
</Window>