在WPF的MVVM设计中有仅有一个控件ComboBox,其IsEditable属性设置为true,该控件绑定后台ViewModel中的数据类型是public ObservableCollection<string> Source,Source的来源是sqlite数据库中的MSJ.db数据库的表Source的数据,该表只有一列数据,列名为Source,表里有两行数据分别为“上级配发”和“本级自购”,要求实现第一点:ComboBoxItem选择发生改变时,弹窗提示用户选择前后的数据;第二点:ComboBox的输入框在接受自定义输入后,判断用户输入不属于ComboBoxItem后,自动将其加入ComboBoxItem中,同时更新后台sqlite数据库的MSJ.db数据库的表Source的数据。请给出实现上述功能的完整实例代码
时间: 2024-02-06 21:09:43 浏览: 112
WPF 在ViewModel中调用 View(界面的控件)
ViewModel代码如下:
```csharp
public class MainViewModel : INotifyPropertyChanged
{
private ObservableCollection<string> _source;
private string _selectedSource;
public ObservableCollection<string> Source
{
get { return _source; }
set
{
if (_source != value)
{
_source = value;
OnPropertyChanged("Source");
}
}
}
public string SelectedSource
{
get { return _selectedSource; }
set
{
if (_selectedSource != value)
{
if (!string.IsNullOrEmpty(_selectedSource))
{
MessageBox.Show($"您选择了{_selectedSource},下一步选择{_selectedSource}");
}
_selectedSource = value;
OnPropertyChanged("SelectedSource");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
```
XAML代码如下:
```xml
<Window x:Class="ComboBoxDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<ComboBox x:Name="comboBox" IsEditable="True" Text="{Binding SelectedSource, Mode=TwoWay}">
<ComboBox.ItemsSource>
<Binding Path="Source"/>
</ComboBox.ItemsSource>
<ComboBox.Style>
<Style TargetType="ComboBox">
<Setter Property="IsDropDownOpen" Value="True" />
<Style.Triggers>
<Trigger Property="Text" Value="{x:Null}">
<Setter Property="IsDropDownOpen" Value="False" />
</Trigger>
</Style.Triggers>
</Style>
</ComboBox.Style>
<ComboBox.InputBindings>
<KeyBinding Key="Enter" Command="{Binding AddSourceCommand}"/>
</ComboBox.InputBindings>
</ComboBox>
</Grid>
</Window>
```
MainWindow.xaml.cs代码如下:
```csharp
public partial class MainWindow : Window
{
private MainViewModel _viewModel;
public MainWindow()
{
InitializeComponent();
_viewModel = new MainViewModel();
DataContext = _viewModel;
LoadData();
}
private void LoadData()
{
string connectionString = "Data Source=MSJ.db;Version=3;";
using (SQLiteConnection connection = new SQLiteConnection(connectionString))
{
connection.Open();
string sql = "SELECT * FROM Source;";
SQLiteCommand command = new SQLiteCommand(sql, connection);
SQLiteDataReader reader = command.ExecuteReader();
ObservableCollection<string> source = new ObservableCollection<string>();
while (reader.Read())
{
source.Add(reader[0].ToString());
}
_viewModel.Source = source;
reader.Close();
connection.Close();
}
}
}
```
在MainWindow.cs中用SQLiteConnection从数据库中读取数据,并将数据绑定到ComboBox上,同时添加了一个按Enter键的InputBinding,用于触发添加自定义输入的Command。AddSourceCommand在ViewModel中实现,代码如下:
```csharp
public class MainViewModel : INotifyPropertyChanged
{
// ...
public ICommand AddSourceCommand { get; set; }
public MainViewModel()
{
AddSourceCommand = new RelayCommand(AddSource);
}
private void AddSource()
{
if (!string.IsNullOrEmpty(SelectedSource) && !Source.Contains(SelectedSource))
{
Source.Add(SelectedSource);
SaveData();
}
}
private void SaveData()
{
string connectionString = "Data Source=MSJ.db;Version=3;";
using (SQLiteConnection connection = new SQLiteConnection(connectionString))
{
connection.Open();
string sql = "DELETE FROM Source;";
SQLiteCommand command = new SQLiteCommand(sql, connection);
command.ExecuteNonQuery();
foreach (string source in Source)
{
sql = $"INSERT INTO Source(Source) VALUES('{source}');";
command = new SQLiteCommand(sql, connection);
command.ExecuteNonQuery();
}
connection.Close();
}
}
}
```
AddSourceCommand的实现简单地判断用户输入是否为空,是否已经存在于ComboBox中,如果不是则添加到Source中,并保存到数据库中。SaveData方法用SQLiteCommand执行SQL语句,删除原有数据并插入新数据。
其中,RelayCommand是一个常用的ICommand实现,请自行搜索相关资料获取代码。
阅读全文