我在TabControl
中生成动态选项卡,每个选项卡的内容应该是填充DataGrid
的视图/UserControl。
数据似乎已经加载,但是绑定有问题,因为视图没有显示任何内容。我认为ViewModel与View本身的绑定不匹配。
x1c 0d1x的数据
如果我在MainWindow.xaml
中添加<views:MachineView DataContext="{Binding}"/>
,我会得到更新的数据,但我需要删除并添加它才能“工作”。
的
MainWindow.xaml
<TabControl x:Name="machineTabs" Grid.Row="1" ItemsSource="{Binding Tabs}" SelectedIndex="{Binding SelectedIndex}" >
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Header}"/>
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate DataType="{x:Type viewModels:MachineViewModel}">
<views:MachineView/>
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
字符串
标签头(<TabControl.ItemTemplate>
)成功绑定到Header
字段,但是当我尝试在视图本身中输出相同的值时,它不显示。
MainWindow.xaml.cs
public partial class MainWindow : Window
{
private readonly MainWindowModel mainWindowModel;
public MainWindow()
{
mainWindowModel = new MainWindowModel();
DataContext = mainWindowModel;
InitializeComponent();
}
}
型
MainWindowModel.cs
public class MainWindowModel : ObservableObject
{
private SqlConnection connection;
public ObservableCollection<MachineViewModel> Tabs { get; } = new ObservableCollection<MachineViewModel>();
public MainWindowModel()
{
connection = new(GetConnectionString());
AddTab("Free");
AddTab("Night Shift");
AddTab("Day Shift");
AddTab("Afternoon Shift");
}
private void AddTab(string header)
{
var mvm = new MachineViewModel();
mvm.Initialize(header, connection);
Tabs.Add(mvm);
}
public ICommand SearchCommand => new RelayCommand(Search);
public int SelectedIndex { get; set; }
/* ... */
}
型
MachineView.xaml
<UserControl x:Class="Namespace.View.MachineView"
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:local="clr-namespace:Namespace.View"
xmlns:vm="clr-namespace:Namespace.ViewModel"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid Background="LightBlue">
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="{Binding Header}" HorizontalAlignment="Center" VerticalAlignment="Center" />
<DataGrid x:Name="DataGrid" Grid.Row="1" ItemsSource="{Binding DataTable}" AutoGenerateColumns="True" IsReadOnly="True"/>
</Grid>
</UserControl>
型
MachineView.xaml.cs
public partial class MachineView : UserControl
{
private readonly MachineViewModel machineViewModel;
public MachineView()
{
machineViewModel = new MachineViewModel();
DataContext = machineViewModel;
InitializeComponent();
}
}
型
MachineViewModel.cs
public sealed class MachineViewModel : ObservableObject
{
public string Header { get; private set; } = "";
private SqlConnection? connection;
private SqlDataAdapter? adapter;
private DataTable? dataTable;
private DataView? dataTableView;
public void Initialize(string header, SqlConnection connection)
{
this.connection = connection;
Header = header;
OnPropertyChanged(nameof(Header));
}
public void Search()
{
if (connection == null) return;
try
{
connection.Open();
using SqlCommandBuilder sqlcommandbuilder = new();
string dmc = sqlcommandbuilder.QuoteIdentifier(Header);
string query = "select xyz";
using SqlCommand command = new(query, connection);
// Init the command and the builder
adapter = new SqlDataAdapter(command);
SqlCommandBuilder commandBuilder = new(adapter);
// Fill the table with the values from the adapter and set it to the public field to notify about changes
dataTable = new DataTable();
adapter.Fill(dataTable);
DataTable = dataTable.DefaultView;
connection.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
public DataView? DataTable
{
get => dataTableView;
set
{
if(dataTableView != value)
{
dataTableView = value;
OnPropertyChanged(nameof(DataTable));
}
}
}
}
型
请注意,必须使用Header
来填充数据表。我喜欢使用构造函数,但xaml需要一个无参数的视图构造函数(?)
为什么即使我将视图绑定到DataTable
并且在更新时调用OnPropertyChanged(nameof(DataTable));
,内容也没有更新?
1条答案
按热度按时间ekqde3dh1#
MachineView不能创建它自己的私有视图模型示例,而是操作它通过其DataContext属性的继承值获得的视图模型。
因此,只需从其构造函数中删除DataContext赋值:
字符串
由于TabControl不会为每个数据项创建新的TabItem和新的MachineView,因此您可以在
DataContextChanged
事件处理程序中“重置”单个MachineView的可视状态:型