c# - 用户控制 MVVM 中的执行方法

标签 c# wpf mvvm user-controls

我正在开发我的第一个 MVVM 应用程序,但无法使其正常工作。

在我的主窗口中,我有一个按钮可以执行返回自定义数据表类型对象的 SQL 命令。

该窗口还包含一个用户控件,该控件由一些列标题和一个 Windows 窗体托管的 DataGridView 组成。我需要以某种方式告诉用户控件执行将数据传递给 DataGridView 的方法,以便它可以更新它的值。

我尝试在我的 WPF 网格控件上创建一个依赖属性,该控件绑定(bind)到我的 View 模型的数据,但它没有正确更新。

我怎样才能让它工作?

--编辑--

这是我的 LiteGrid 用户控件的 XAML -

<UserControl x:Class="ReportUtility.Controls.LiteGrid.LiteGrid"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
         xmlns:lite="clr-namespace:ReportUtility.Controls.LiteGrid"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300"
         DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="30"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <ScrollViewer x:Name="_scroll" VerticalScrollBarVisibility="Hidden" HorizontalScrollBarVisibility="Hidden">
        <ItemsControl ItemsSource="{Binding Columns}" Grid.Row="0" Background="AliceBlue">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate> 
                        <StackPanel Orientation="Horizontal"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ItemsControl>
    </ScrollViewer>
    <WindowsFormsHost Background="White" Grid.Row="1">
        <lite:LiteGridView x:Name="_liteGridView"/>
    </WindowsFormsHost>
</Grid>

我的主要 View 模型是:

public class MainWindowViewModel : DependencyObject
{
    private readonly ILiteTableSource _source;

    public ICommand ExecuteQueryCommand { get; set; }
    public LiteGridViewModel Grid { get; set; }
    public string SqlCommandText { get; set; }

    public MainWindowViewModel(ILiteTableSource source)
    {
        this.ExecuteQueryCommand = new ExecuteQueryCommand(this);

        _source = source;
        _source.DataArrived+=new Action<DataSources.LiteSource.LiteTable>(_source_DataArrived);
    }

    public void ExecuteQuery()
    {
        _source.Connection = new ServerConnection();
        _source.CommandText = this.SqlCommandText;
        _source.ExecuteQuery();
    }

    public LiteTable Results
    {
        get { return (LiteTable)GetValue(ResultsProperty); }
        set { SetValue(ResultsProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Results.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ResultsProperty =
        DependencyProperty.Register("Results", typeof(LiteTable), typeof(MainWindowViewModel), new UIPropertyMetadata(null));

    void _source_DataArrived(LiteTable data)
    {

        this.Results = data;
    }
}

XAML:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="auto"/>
        <RowDefinition Height="50"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <Button Grid.Row="0" Content="TestButton" HorizontalAlignment="Stretch" Command="{Binding ExecuteQueryCommand}"/>
    <TextBox Grid.Row="1" Text="{Binding Path=SqlCommandText, UpdateSourceTrigger=PropertyChanged}"/>
    <lite:LiteGrid Grid.Row="2" Data="{Binding Data, UpdateSourceTrigger=PropertyChanged}"/>
</Grid>

最佳答案

因为你有一个 LiteGridViewModel和你的LiteGrid一起去,为什么不直接从 ViewModel 执行命令?

使用您问题中发布的代码,我会:

将此添加到资源以确保 LiteGridViewModel使用 LiteView 绘制

<Window.Resources> <!-- Or Grid.Resources if you prefer -->
    <DataTemplate DataType="{x:Type lite:LiteGridViewModel}">
        <lite:LiteGrid />
    </DataTemplate>
</Window.Resources>

替换 <lite:LiteGrid ... />控制在 MainView使用 ContentControl 来显示 ViewModel

<ContentControl Content="{Binding Grid}" />

删除 Data属性(property)上MainViewModel因为它应该存储在 LiteGridViewModel 中, 不是 MainViewModel

在你的MainWindowViewModel使用 LiteGridViewModel而不是尝试通过 View 使用 ViewModel

Grid = new LiteGridViewModel();

void _source_DataArrived(LiteTable data)
{
    Grid.Data = data;  // Fill property in ViewModel
    Grid.UpdateData(); // Call command on ViewModel
}

关于c# - 用户控制 MVVM 中的执行方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6986404/

相关文章:

c# - 没有语法高亮

c# - WebRequest.GetResponse 锁定?

python - 使用 python 设置背景图像

c# - Prism WPF : Loading a User Control on Startup

c# - 用字符串路径绑定(bind)背景

c# - 从脚本启用/禁用游戏对象组件 [Unity3D]

c# - 将图片嵌入到 outlook 电子邮件正文

c# - 运行 WPF 应用程序框架示例时遇到问题

c# - WPF:以编程方式更改具有自定义样式的控件的颜色

c# - 在接收消息时创建 View