c# - 从 ViewModel 向 View 发送命令是否违反了 MVVM?

标签 c# wpf mvvm datagrid

我希望我的 DataGrid 滚动到底部,因为新项目添加到底层 ObservableCollection 中。为了实现这一点,我制作了一个类似于 ICommand 的接口(interface),但采用的是“反向”方式。

public interface IViewModelCommand
{
    void Execute(object parameter);
}

实现

public class ViewModelRelayCommand : IViewModelCommand
{
    private readonly Action<object> _action;
    public ViewModelRelayCommand(Action<object> action)
    {
        if(action == null)
            throw new ArgumentNullException("action");

        _action = action;
    }

    public void Execute(object parameter)
    {
        _action(parameter);
    }
}

我的 View 模型

    private IViewModelCommand _scrollAction;
    public IViewModelCommand ScrollAction
    {
        get { return _scrollAction; }
        set
        {
            if (_scrollAction == value)
                return;
            _scrollAction = value;OnPropertyChanged();
        }
    }

然后我为我的 DataGrid 创建行为。 (滚动到取自 here 的结束代码)

public sealed class DataGridBehavior : Behavior<DataGrid>
{
        public static readonly DependencyProperty ScrollToEndProperty =
            DependencyProperty.Register (
                "ScrollToEnd",
                typeof(IViewModelCommand),
                typeof(DataGridBehavior),
                new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.None)
            );

        public IViewModelCommand ScrollToEnd
        {
            get { return (IViewModelCommand)GetValue(ScrollToEndProperty); }
            set { SetValue(ScrollToEndProperty, value); }
        }

        protected override void OnAttached()
        {
            base.OnAttached();
            ScrollToEnd = new ViewModelRelayCommand(Scroll);
        }

        protected override void OnDetaching()
        {
            base.OnDetaching();
            ScrollToEnd = null;
        }

        private void Scroll(object parameter)
        {
            var mainDataGrid = AssociatedObject;
            if (mainDataGrid.Items.Count > 0)
            {
                var border = VisualTreeHelper.GetChild(mainDataGrid, 0) as Decorator;
                if (border != null)
                {
                    var scroll = border.Child as ScrollViewer;
                    if (scroll != null) scroll.ScrollToEnd();
                }
            }
        }
    }

并将其附加到我的 DataGrid

        <i:Interaction.Behaviors>
            <local:DataGridBehavior ScrollToEnd="{Binding ScrollAction, Mode=OneWayToSource}" />
        </i:Interaction.Behaviors>

然后从我的 ViewModel 中,我只需调用 if (_scrollAction != null) _scrollAction.Execute(null); 来滚动我的网格,效果非常好。

我的问题是,这是否违反了 MVVM?

最佳答案

就一点点...

根据我的经验,MVVM 作为粗略指南是最健康的实践。当您的实际编程任务不需要时,寻找保持 MVVM 正常运行的解决方案是没有用的,尤其是当您已经启动并运行了可行的解决方案时。

但是你有没有想过用事件来代替命令方法?

在这种情况下,这可能对您有用:How can I Have a WPF EventTrigger on a View trigger when the underlying Viewmodel dictates it should?

关于c# - 从 ViewModel 向 View 发送命令是否违反了 MVVM?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29091127/

相关文章:

c# - 带有参数的 Cosmosdb documentdb Sql 查询返回 0 个项目

c# - 我如何获得 XElement 的第一个 child ?

WPF VirtualizingStackPanel 以提高性能

c# - 如何在没有任何数据绑定(bind)的情况下以编程方式添加多列 ListViewItem?

c# - 为什么 VS2010 IntelliSense 在使用动态参数链接方法时失败

c# - 无法将文件复制到 WPF 中的 Environment.SpecialFolder.Startup

c# - 留言后发送留言

silverlight - 数据网格列按钮命令(MVVM)

c# - 在 C# (WPF) 中,当 UI 线程中的数据立即更改时,是否会发生数据绑定(bind)?

c# - 通过 Internet 问题设置 TCP/IP 连接