SO的新手和我的第一个问题。
我花了一天时间研究并试图解决这个问题。我发现的所有示例都显示通过按钮点击将所有内容放在代码中。或者一些将SQL逻辑放在ViewModel中。我正在尝试将SQL逻辑保持在视图之外并查看模型。
我有一个用户输入搜索值的文本框。根据SQL Server表搜索该值。我在使用断点时看到了这些值,所以一切都在努力。我之后无法弄清楚如何在DataGrid中显示它们。退出循环时,这些值会丢失。
如果我将自动生成的列更改为“True”,我会看到列名称,所以我认为绑定设置正确。设置为“True”时,它还会显示名称Has Errors列,这看起来很奇怪。
如何在DataGrid中显示此数据?我认为问题是因为我没有返回这些值,但我不确定如何在我当前的场景中实现这一点。我是否会犯这个错误,需要以不同的方式做到这一点?我应该使用DataReader吗?
我错过了什么和/或做错了什么?
Person.cs
public class Person : ValidationBase
{
private string lastname;
public string LastName
{
get { return lastname; }
set
{
if (lastname != value)
{
lastname = value;
OnPropertyChanged();
}
}
}
private string firstname;
public string FirstName
{
get { return firstname; }
set
{
if (firstname != value)
{
firstname = value;
OnPropertyChanged();
}
}
}
private string emailaddress;
public string EmailAddress
{
get { return emailaddress; }
set
{
if (emailaddress != value)
{
emailaddress = value;
OnPropertyChanged();
}
}
}
}
模型
public static bool SearchUser(string UserLookupTextBox) //<-- Textbox value from ViewModel
{
using (SqlConnection con = new SqlConnection(connectionString))
using (SqlCommand cmd = new SqlCommand("Select [LastName], [FirstName], [EmailAddress] from [User] where (LastName=@Lookup)", con))
{
var person = new Person();
cmd.Parameters.Add("@Lookup", SqlDbType.VarChar).Value = UserLookupTextBox.Trim()
DataTable dt = new DataTable();
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(dt);
for (int i = 0; i < dt.Rows.Count; ++i)
{
person.LastName = dt.Rows[i][0].ToString();
person.FirstName = dt.Rows[i][1].ToString();
person.EmailAddress = dt.Rows[i][2].ToString();
//how do I return this to Person or to datagrid??
};
} //<--Values get lost here
return true;
}
视图模型
private ObservableCollection<Person> updateusersearch = new ObservableCollection<Person>();
public ObservableCollection<Person> UpdateUserSearch
{
get { return updateusersearch; }
set
{
updateusersearch = value;
OnPropertyChanged();
}
}
private void ExecuteSearchUser(object parameter)
{
bool SearchUser = NewUserModel.SearchUser(UserLookupTextBox); <--passing textbox value to Model
}
public NewUserViewModel()
{
SearchUserCommand = new RelayCommand(ExecuteSearchUser, CanExecuteSearchUser);
}
XAML
<DataGrid //<--Cut everything else to keep short. Others columns identical setup
DataContext="{Binding UpdateUserSearch}"
ItemsSource="{Binding}">
<DataGrid.Columns>
<DataGridTextColumn
Header="Last Name"
Binding="{Binding LastName, Mode=TwoWay, ValidatesOnNotifyDataErrors=True, UpdateSourceTrigger=PropertyChanged,ValidatesOnExceptions=True, NotifyOnValidationError=True}">
<DataGridTextColumn.HeaderStyle>
<Style TargetType="DataGridColumnHeader">
<Setter Property="HorizontalContentAlignment"
Value="Center" />
</Style>
</DataGridTextColumn.HeaderStyle>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
这是我的解决方案。每个评论者都以某种方式帮助过,谢谢大家的帮助。我仍然觉得有更好的方法(除了提到的Entity Framework)。希望其他人将来会为其他人添加这些方法。我也将关注EF的未来发展方向。您在网上找到的材料中有80%或更多可能会告诉您如何做错事。他们教你编写SQL注入代码。使用WPF按钮单击。等等。那里需要更多“好”的内容。也许这会在某些时候帮助别人。它完成了我在datagrid中加载的目标。
以下是所做的更改。如果您没有看到它与发布的相同内容。除了我将UpdateUserSearch更改为UserSearch之外,在XAML和ObservableCollection中进行了更改。
查看模型
private void ExecuteSearchUser(object parameter)
{
LoadUserSearch();
}
NewUserModel.UserSearch model = new NewUserModel.UserSearch();
private void LoadUserSearch()
{
DataTable table = model.GetUserData(UserLookupTextBox, SearchByComboBox);
for (int i = 0; i < table.Rows.Count; ++i)
UserSearch.Add(new Person()
{
LastName = table.Rows[i][0].ToString(),
FirstName = table.Rows[i][1].ToString(),
EmailAddress = table.Rows[i][2].ToString(),
});
table.Dispose();
}
模型
public class UserSearch
{
public DataTable GetUserData(string UserLookupTextBox, string SearchByComboBox)
{
using (SqlConnection con = new SqlConnection(connectionString))
using (DataTable dt = new DataTable())
if (SearchByComboBox == "Last Name")
{
using (SqlCommand cmd = new SqlCommand("Select [LastName], [FirstName], [EmailAddress] from [DbUser] where (LastName=@Lookup)", con))
{
cmd.Parameters.Add("@Lookup", SqlDbType.VarChar).Value = UserLookupTextBox.Trim();
using (SqlDataAdapter da = new SqlDataAdapter(cmd))
{
da.Fill(dt);
return dt;
}
}
}
else
{
........
}
}
}
}