在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-11 21:09:27 浏览: 118
以下是实现上述功能的完整实例代码:
XAML代码:
```xml
<Window x:Class="ComboBoxExample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:ComboBoxExample.ViewModels"
Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
<vm:MainViewModel />
</Window.DataContext>
<Grid>
<ComboBox ItemsSource="{Binding Source}" SelectedItem="{Binding SelectedItem, Mode=TwoWay}" IsEditable="True" Text="{Binding SelectedItem}" Width="200" Margin="20" />
</Grid>
</Window>
```
ViewModel代码:
```csharp
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using System.Data.SQLite;
using System.IO;
namespace ComboBoxExample.ViewModels
{
public class MainViewModel : ViewModelBase
{
private ObservableCollection<string> _source;
public ObservableCollection<string> Source
{
get { return _source; }
set { _source = value; OnPropertyChanged(); }
}
private string _selectedItem;
public string SelectedItem
{
get { return _selectedItem; }
set
{
if (_selectedItem != value)
{
// 弹窗提示用户选择前后的数据
if (!string.IsNullOrEmpty(_selectedItem))
{
var result = MessageBox.Show($"是否将 {_selectedItem} 修改为 {value}?", "提示", MessageBoxButton.YesNo);
if (result == MessageBoxResult.No)
{
// 如果用户取消选择,则将 ComboBox 的选中值重置为之前的值
SelectedItem = _selectedItem;
return;
}
}
_selectedItem = value;
// 如果用户输入的值不属于 ComboBoxItem,则将其加入 ComboBoxItem 中,并更新数据库
if (!Source.Contains(value))
{
Source.Add(value);
// 更新数据库
string dbPath = "MSJ.db";
if (!File.Exists(dbPath))
{
SQLiteConnection.CreateFile(dbPath);
}
using (var connection = new SQLiteConnection($"Data Source={dbPath}"))
{
connection.Open();
using (var command = new SQLiteCommand(connection))
{
command.CommandText = "CREATE TABLE IF NOT EXISTS Source (Source TEXT)";
command.ExecuteNonQuery();
command.CommandText = $"INSERT INTO Source (Source) VALUES ('{value}')";
command.ExecuteNonQuery();
}
}
}
OnPropertyChanged();
}
}
}
public MainViewModel()
{
// 从数据库读取数据
string dbPath = "MSJ.db";
if (!File.Exists(dbPath))
{
SQLiteConnection.CreateFile(dbPath);
}
using (var connection = new SQLiteConnection($"Data Source={dbPath}"))
{
connection.Open();
using (var command = new SQLiteCommand(connection))
{
command.CommandText = "CREATE TABLE IF NOT EXISTS Source (Source TEXT)";
command.ExecuteNonQuery();
command.CommandText = "SELECT * FROM Source";
using (var reader = command.ExecuteReader())
{
Source = new ObservableCollection<string>();
while (reader.Read())
{
Source.Add(reader.GetString(0));
}
}
}
}
}
}
}
```
其中,ViewModelBase 继承自 INotifyPropertyChanged 接口,用于实现属性变更通知。完整代码如下:
```csharp
using System.ComponentModel;
namespace ComboBoxExample.ViewModels
{
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
```
阅读全文