WPF通过双向数据绑定通过DataTemplate中的TextBox输入来更新所选对象的数据库

时间:2018-09-24 05:24:53

标签: c# wpf xaml

作为主题,我在通过在TextBox中输入新数据来更新数据库时遇到问题。我已经在网上搜索答案很长时间了。我也有几个类似的问题和答案,但似乎没有答案可以解决我的特定问题。

我的WPF应用程序的结构是我有MainWindow的两个部分,在左边有一个ListBox,列出了我添加到数据库中的所有对象。当我选择一个对象时,该对象的详细信息可以显示在ContentControlTabControl的右侧。此问题中的TextBox是在DataTemplate引用的ResourceDictionary中定义的。

我这里实际上有两个问题。一个是我无法从TextBox下的DataTemplate的{​​{1}}中获得输入文本。另一个是我无法从ContentControl的后端代码中获取所选对象。我的应用程序的代码结构如下。

MainWindow.xaml:

DictionaryResource

我有一个名为<Window> <Grid> <Grid.ColumnDefinition> <Grid.ColumnDefinition Width="*" /> <Grid.ColumnDefinition Width="*" /> </Grid.ColumnDefinition> <ListBox x:Name="MyListBox" Grid.Column="0" ItemSource="{Binding Objects}" SelectedItem="{Binding SelectedObject}" /> <TabControl Grid.Column="1"> <TabItem Header="First Tab"> <ContentControl x:Name="FirstContent" Content="{Binding SelectedObject}" ContentTemplate="{StaticResource FirstTemplate}" /> </TabItem> </TabControl> </Grid> </Window> 的对象,它具有一些属性,例如 Id Name Material 。我正在使用的数据库是Unit。 MainWindow.xaml.cs:

sqlite-net-pcl

ViewModel.cs:

public partial class MainWindow
{
    ViewModel vm = new ViewModel();
    public MainWindow()
    {
        DataContext = vm;
        vm.LoadData();
        InitializeComponent();
    }    
 }

我有这个Class ViewModel: INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; public ObservableCollection<Object> Objects {get; } = new ObservableCollection<Object>(); private Object _selectedObject; private Object SelectedObject { get {return _selectedObject;} set { _selectedObject = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedObject))); } } public void UpdateData() { using (var conn = new SQLiteConnection("databasepath") { conn.Update(SelectedObject); // This SelectedObject is always null. } } public void LoadData() { using (var conn = new SQLiteConnection("Some path") { conn.CreateTable<Unit>(); List<Unit> units = conn.Table<Unit>().ToList(); if (units != null) { foreach (var unit in units) { vm.Objects.Add(unit); } } } } } 的原因是我实际上有两种不同的对象,它们具有不同的DataTemplates。您可以参考我之前的问题,以了解更多详细信息here

ResourceDictionary TemplateSetup.xaml:

ViewModel

TemplateSetup.xaml.cs:

<ResourceDictionary>
    <DataTemplate x:Key="FirstTemplate" DataType="{x:Type local:Unit}">
      <Grid>
        <Border x:Name="SomeBorder">
            <TextBox x:Name="WantedTextBox"
                     Text="{Binding Path=Material, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> 
        </Border>
        <Button Click="MyButton_OnClick" />
      </Grid>
    </DataTemplate>
</ResourceDictionary>                         

我尝试解决SelectedObject问题的一种方法是将整个DataTemplate放在MainWindow.xaml中,但实际上DataTemplate相当长,我想使代码干净且易于管理,因此将其移至{ {1}}。有没有一种方法可以将此SelectedObject与我在MainWindow中选择的对象链接起来?

对于第二个问题,我读了article。但是它的DataTemplate在public partial class TemplateSetup : ResourceDictionary { public TemplateSetup() { InitializeComponent(); } Private void MyButton_OnClick(object sender, RoutedEventArgs e) { var vm = new ViewModel(); vm.UpdateData(); //It is not working here. } } 下,所以我不知道如何在ResourceDictionary情况下更改ListBox。我也读过这个answer,但是代码ListBoxItem给了我一个错误。

谢谢您的帮助!

编辑:

作为SirRufo的代码示例,我在ViewMode.cs中更改了ContentControlchildElement = (T)child;。但是,SelectedObject始终向我返回null。我的想法是,我不需要访问TextbBox,因为TwoWay绑定已经捕获了我的输入。但是,如何将输入与数据库中的对象链接,以便可以对其进行更新?

0 个答案:

没有答案