WPF 和 MVVM 问题

标签 wpf mvvm delegatecommand

如果尝试在 WPF 应用程序中实现我的第一个 MVVM。我有基于 winforms 的旧应用程序,我想使用这个项目中的逻辑(类)。

我有模型,它包含以下类:

public class FriendData
{
//...
}

public class PingData
{
//...
}

public class PokecAccount : INotifyPropertyChanged, IDataErrorInfo
{
//...
}


public class Rp :INotifyPropertyChanged, IDataErrorInfo
{
//...
}


public class JsonUser:INotifyPropertyChanged
{
//...
}

以及在服务器上发送 HTTP GET 和 POST 请求的服务类,这个类实现了这个接口(interface):
interface IPokecService
{
    bool LogOn(string nick, string password);
    bool LogOff();
    JsonUser CreateJsonUser(string nick);
    void Ping();
    void IbRp();
    bool SendRp(Rp rp);
    Rp LoadRp();
}


public class PokecService:IPokec
{
 public PokecAccount account;
 public PingData pingData;

 //impelent interface IPokec

}

我尝试使用 WPF Model-View-ViewModel Toolkit 0.1 中的 DelegateCommand。

使用 View 我有任何问题。但我的问题是如何从 ViewModel 中的类 PokecService 中“包装”方法。

使用方法 LogOn 的示例。

首先我创建 看法。

StartUpWindow.xaml
    <StackPanel Grid.Row="1" Margin="12,12,12,12">
        <Label Name="lbAzetID" Content="AzetID" Style="{StaticResource lb1}"></Label>
        <TextBox Name="tbAzetID" Style="{StaticResource tb1}">
            <TextBox.Text>
                <Binding Path="AzetId" Mode="OneWayToSource" UpdateSourceTrigger="PropertyChanged">
                </Binding>
            </TextBox.Text>
        </TextBox>
        <Label Name="lbRegistration" Content="Registrácia" Style="{StaticResource lb1}">
            <Label.ToolTip>
                <StackPanel>
                    <TextBlock FontWeight="Bold">Registrácia</TextBlock>
                    <TextBlock>Nemáte vlástené AzetID, registrujte sa tu!</TextBlock>
                </StackPanel>
            </Label.ToolTip>
        </Label>
        <Label Name="lbPassword" Content="Heslo" Style="{StaticResource lb1}" ></Label>
        <TextBox Name="tbPassword" Style="{StaticResource tb1}">
            <TextBox.Text>
                <Binding Path="Password" Mode="OneWayToSource" UpdateSourceTrigger="PropertyChanged">
                </Binding>
            </TextBox.Text>
        </TextBox>
        <Label Name="lbForgetPassword" Content="Zabudli ste heslo?" Style="{StaticResource lb1}">
            <Label.ToolTip>
                <StackPanel>
                    <TextBlock FontWeight="Bold">Zabudli ste svoje heslo?</TextBlock>
                    <TextBlock>Nechajte si ho zaslať na Váš email.</TextBlock>
                </StackPanel>
            </Label.ToolTip>
        </Label>
    </StackPanel>
    <Button Name="LogOn"
            Command="{Binding LogOnCommand}"
            Content="Prihlásiť" 
            Width="100" 
            Height="25" 
            VerticalAlignment="Center"
            Grid.Row="2" />

它只包含 2 个 texboxes 和一个按钮,我在 ViewModel 的属性上绑定(bind)了按钮 commad。

View 模型
StartUpViewModel.cs


在这个类中,我想在 DelegateCommand 上包装 PokecService 类的方法,并将这些方法绑定(bind)到 UI 控件上。
public class StartUpViewModel
{

    private string _name = "KecMessanger";
    private string _password = "KecMessanger";
    private PokecService _pokecService;

    public StartUpViewModel()
    {
        _pokecService=new PokecService();
    }

    DelegateCommand _logOnCommand;

    public ICommand LogOnCommand
    {
        get
        {
            if(_logOnCommand==null)
            {
                _logOnCommand=new DelegateCommand(LogOn,CanLogOn);
            }
            return _logOnCommand;
        }
    }

    private void LogOn()
    {
        //In this method I need to call method LogOn from calss PokecService _pokecService.LogOn(_name,_password)          
        //if loging is success I need create another window - view and close this window
        //somehing like this:
        if (_pokecService.LogOn(_name, _password))
        {
            var newViewWindow = new AnotherView();
            //close StartUpView (its typeof window) but I don’t know how
            AnotherView.Show();
        }           
    }

    private bool CanLogOn()
    {
        return true;
    }
}

我的问题是:
  • 我可以从 ViewModel 中的属性 View 中绑定(bind) UI 控件,这没问题。
    在 ViewModel 中使用 DelegateCommad 从我的类 PokecService 中“包装”方法是一种好方法吗?
  • 在 ViewModel 中创建新窗口/ View 很好吗?如何关闭 ViewModel 中的实际 View (窗口)?
  • 这个问题最合适的解决方案是什么?

  • 我想我只需要用 DelegateCommand 变量包装我的方法,并为这些变量属性创建这些属性,并且这些属性绑定(bind)在 UI 控件上,但我是 MVVM 的绝对初学者。我读了一些文章,但它们只展示了非常简单的演示。

    感谢任何提前。对不起我的英语不好。

    最佳答案

  • 命令用于在 MVVM 中的 View 和 View 模型之间进行通信。要将 PokecService 从 ViewModel 中抽象出来,我建议您使用依赖注入(inject)(我自己使用 MEF)。
  • 我将为 View 提供依赖注入(inject),因此该类更易于测试。如果需要,请创建一个接口(interface),以便您可以替换服务类的实际实现,而无需在任何地方替换类型。
  • 使用 DI 容器。

  • 注意:我使用 WAF作为 MVVM 框架与 MEF 一起使用,它就像一个魅力。

    简短的例子:
    [Export(typeof(IService))]
    public class Service : IService
    {
    }
    
    public interface IService
    {
      void Method();
    }
    
    [Export]
    public class Consumer
    {
      private readonly IService _Service;
    
      [ImportingConstructor]
      public Consumer(IService service)
      {
        ser = service;
      }
    
    
      public void DoStuff()
      {
        //stuff
        _Service.Method();
      }
    }
    

    在启动方法中(即 Application.OnStartup ):
    var catalog = new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly()); //insert the assembly defining the mentioned classes above
    var container = new CompositionContainer(catalog);
    container.ComposeParts(this);
    
    Consumer c = container.GetExportedValue<Consumer>();
    c.DoStuff();
    

    关于WPF 和 MVVM 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4234412/

    相关文章:

    wpf - 如何在 wpf 中加载窗口时触发命令

    c# - WPF CommandParameter 绑定(bind)和 canExecute

    c# - 在 ViewModel 中创建 KeyBinding 时添加参数

    java - 无法使用 dagger2 android java 注入(inject) ViewModel

    .net - 无法订阅 DelegateCommand.CanExecuteChanged

    c# - 将 NHibernate 集合延迟加载到 ViewModel 中?

    java - Android 自定义下拉 View 与动态列表

    c# - enter press 不会引发属性更改事件 wpf

    wpf - 使 WPF 组合框填充整个列宽

    c# - 基于绑定(bind)数据的 MenuItem 模板更改