【问题标题】:Loading a UserControl in WPF DataGrid在 WPF DataGrid 中加载用户控件
【发布时间】:2021-11-25 17:14:18
【问题描述】:

我正在构建一个 WPF MVVM 应用程序。我正在尝试在 Grid 中加载 UserControl,但 OnLoaded 方法不会触发。

这里是UserControl中的EventTrigger,叫Selector

<b:Interaction.Triggers>
        <b:EventTrigger EventName="Loaded">
            <b:InvokeCommandAction Command="{Binding OnLoadedCommand}" />
        </b:EventTrigger>
</b:Interaction.Triggers>

这是SelectorViewModel中的代码:

public RelayCommand OnLoadedCommand { get; set; }

public SelectorViewModel(MapService mapService)
{
      this.mapService = mapService ?? throw new ArgumentNullException(nameof(mapService));

      OnLoadedCommand = new RelayCommand(OnLoaded);
}

public async void OnLoaded()
{
      AvailablePositions = await mapService.GetPositions();
      //other code
}

UserControl 加载到的网格的View

<local:Selector Grid.Row="0" Margin="{StaticResource SmallLeftTopMargin}" />

网格的ViewModelUserControl 被加载到:

public SelectorViewModel SelectorViewModel { get; set; }

public MapViewModel(MapService mapService)
{
      SelectorViewModel = new SelectorViewModel(mapService);
}

根本没有调用该方法的可能原因是什么?我在SelectorViewModel 的构造函数中放了一个断点,它命中了它,但它没有命中OnLoaded() 中的那个。

方法是async这个事实有问题吗?

编辑:

我尝试将命令设置为:

OnLoadedCommand = new RelayCommand(async () => await OnLoaded());

并将OnLoaded 的返回类型从void 更改为Task,但仍然无效。

【问题讨论】:

    标签: c# wpf datagrid user-controls


    【解决方案1】:

    您可以使用Command 绑定它,如下所示。我测试了它的工作原理。

    Xaml 代码

           <DataGrid>
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="Loaded">
                    <i:InvokeCommandAction Command="{Binding OnLoadedCommand}"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </DataGrid>
    

    视图模型

    class MainWindowViewModel
        {
            public AsyncCommand OnLoadedCommand { get; set; }
    
            public MainWindowViewModel()
            {
                OnLoadedCommand = new AsyncCommand(async () => await OnLoaded());
            }
    
            public async Task OnLoaded()
            {
                Console.WriteLine("Loaded");
            }
        }
    

    异步命令

    public interface IAsyncCommand : ICommand
    {
        Task ExecuteAsync(object parameter);
    }
    
    public class AsyncCommand : AsyncCommandBase
    {
        private readonly Func<Task> _command;
        public AsyncCommand(Func<Task> command)
        {
            _command = command;
        }
        public override bool CanExecute(object parameter)
        {
            return true;
        }
        public override Task ExecuteAsync(object parameter)
        {
            return _command();
        }
    }
    

    AsyncCommandBase

    public abstract class AsyncCommandBase : IAsyncCommand
    {
        public abstract bool CanExecute(object parameter);
        public abstract Task ExecuteAsync(object parameter);
        public async void Execute(object parameter)
        {
            await ExecuteAsync(parameter);
        }
        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }
        protected void RaiseCanExecuteChanged()
        {
            CommandManager.InvalidateRequerySuggested();
        }
    }
    

    我还建议您订阅链接here中的方法。

    您可以查看here了解更多详细信息。

    【讨论】:

    • 它仍然不起作用,不知道为什么,我编辑了我的问题并提供了完整的解释。
    • 我正在为你编辑答案。
    猜你喜欢
    • 2014-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-06
    • 2023-04-05
    • 2012-08-14
    相关资源
    最近更新 更多