Как тема, у меня проблема с обновлением базы данных путем ввода новых данных в TextBox
.Я долго искал ответы в Интернете.Я получил несколько похожих вопросов и ответов, но, похоже, что ответы не могут решить мою конкретную проблему.
Структура моего приложения WPF состоит в том, что у меня есть две части MainWindow
, с левой стороны естьListBox
, в котором перечислены все объекты, которые я добавляю в базу данных.Когда я выбираю объект, детали объекта могут быть показаны справа на ContentControl
или TabControl
.TextBox
в этой задаче определено в DataTemplate
, указанном в ResourceDictionary
.
У меня тут две проблемы.Во-первых, я не могу получить входной текст из TextBox
в DataTemplate
в ContentControl
.Другой - я не могу получить выбранный объект из внутреннего кода DictionaryResource
.Структура кода моего приложения выглядит следующим образом.
MainWindow.xaml:
<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>
У меня есть объект с именем Unit
, у него есть некоторые свойства, такие как Id , Имя и Материал .База данных, которую я использую - sqlite-net-pcl
.MainWindow.xaml.cs:
public partial class MainWindow
{
ViewModel vm = new ViewModel();
public MainWindow()
{
DataContext = vm;
vm.LoadData();
InitializeComponent();
}
}
ViewModel.cs:
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);
}
}
}
}
}
Причина, по которой у меня есть ViewModel
, заключается в том, что у меня есть два разных типа объектов, которые имеютразные шаблоны данных.Вы можете обратиться к моему прежнему вопросу, чтобы увидеть более подробную информацию здесь .
ResourceDictionary TemplateSetup.xaml:
<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>
TemplateSetup.xaml.cs:
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.
}
}
Один способ, которым я пытался решить проблему SelectedObject, - поместить весь DataTemplate в MainWindow.xaml, но на самом деле DataTemplate довольно длинный, я хочу сделать свой код чистым и управляемым, поэтому я переместил егодо ResourceDictionary
.Есть ли способ связать этот SelectedObject с тем, который я выбрал в MainWindow?
Для второго вопроса я прочитал эту статью .Но его DataTemplate находится под ListBox
, поэтому я не знаю, как изменить ListBoxItem
в ContentControl
сценарии.Я также прочитал этот ответ , но код childElement = (T)child;
выдает ошибку.
Спасибо за помощь!
Редактировать:
Как пример кода SirRufo, я изменил LoadData()
и UpdateData()
в ViewMode.cs.Но все же SelectedObject всегда возвращает мне ноль.Я понял, что мне не нужен доступ к TextbBox, потому что привязка TwoWay уже захватывает мой ввод.Но как мне связать мой ввод с объектом в базе данных, чтобы его можно было обновить?