WPF Обновление базы данных выбранного объекта путем ввода TextBox в DataTemplate через двустороннюю привязку данных - PullRequest
0 голосов
/ 24 сентября 2018

Как тема, у меня проблема с обновлением базы данных путем ввода новых данных в 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 уже захватывает мой ввод.Но как мне связать мой ввод с объектом в базе данных, чтобы его можно было обновить?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...