作为主题,我在通过在TextBox
中输入新数据来更新数据库时遇到问题。我已经在网上搜索答案很长时间了。我也有几个类似的问题和答案,但似乎没有答案可以解决我的特定问题。
我的WPF应用程序的结构是我有MainWindow
的两个部分,在左边有一个ListBox
,列出了我添加到数据库中的所有对象。当我选择一个对象时,该对象的详细信息可以显示在ContentControl
中TabControl
的右侧。此问题中的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中更改了ContentControl
和childElement = (T)child;
。但是,SelectedObject始终向我返回null。我的想法是,我不需要访问TextbBox,因为TwoWay绑定已经捕获了我的输入。但是,如何将输入与数据库中的对象链接,以便可以对其进行更新?