我正在开发我的第一个MVVM应用程序,并且无法使其正常工作。
在我的主窗口中,我有一个按钮,它执行一个返回自定义数据表类型对象的SQL命令。
该窗口还包含一个用户控件,该控件由一些列标题和一个托管DataGridView的窗体组成。我需要以某种方式告诉用户控件执行一个将数据传递给DataGridView的方法,以便它可以更新它的值。
我尝试在我的WPF网格控件上创建一个依赖属性,该属性绑定到我的viewmodel的数据,但它没有正确更新。
我怎样才能让它发挥作用?
- 编辑 -
这是我的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>
我的主要观点模型是:
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>
答案 0 :(得分:4)
由于你的LiteGridViewModel
有LiteGrid
,为什么不直接从ViewModel执行命令?
使用您问题中发布的代码,我会:
将此添加到参考资料中,以确保使用LiteGridViewModel
LiteView
<Window.Resources> <!-- Or Grid.Resources if you prefer -->
<DataTemplate DataType="{x:Type lite:LiteGridViewModel}">
<lite:LiteGrid />
</DataTemplate>
</Window.Resources>
使用ContentControl替换<lite:LiteGrid ... />
中的MainView
控件以显示ViewModel
<ContentControl Content="{Binding Grid}" />
删除Data
上的MainViewModel
属性,因为它应存储在LiteGridViewModel
中,而不是MainViewModel
使用MainWindowViewModel
进行LiteGridViewModel
工作,而不是通过视图尝试使用ViewModel
Grid = new LiteGridViewModel();
void _source_DataArrived(LiteTable data)
{
Grid.Data = data; // Fill property in ViewModel
Grid.UpdateData(); // Call command on ViewModel
}
答案 1 :(得分:0)
public LiteTable Data
{
get { return (LiteTable)GetValue(DataProperty); }
set
{
object oldvalue = Data;
SetValue(DataProperty, value);
OnPropertyChanged(new DependencyPropertyChangedEventArgs(DataProperty, oldvalue, value));
}
}
// Using a DependencyProperty as the backing store for Data. This enables animation, styling, binding, etc...
public static readonly DependencyProperty DataProperty =
DependencyProperty.Register("Data", typeof(LiteTable), typeof(LiteGrid), new UIPropertyMetadata(null));
试试这个......