我有一个包含许多窗体的C#项目。我还有一个单独的表单来搜索数据库中的数据。所有表单都通过传递搜索所需的参数来调用一个搜索表单,所选结果将返回到调用表单上的文本框。我可以通过传递参数来搜索和查找值。我的问题是如何将所选值返回到调用表单,因为它是动态的?我编写了以下代码将值返回到一个表单,这很有效。但它只适用于一种形式。我只是想知道如何根据调用表单使其变量?
将值传递回调用表格
(System.Windows.Forms.Application.OpenForms["Form1"] as Form1)
.LoadSearchResult(SResult1,SResult2);
答案 0 :(得分:1)
您可以返回填充搜索结果的DataTable
。
DataTable
可以有动态列,具体取决于调用表单。
希望它有所帮助!!!
答案 1 :(得分:0)
我建议使用Dapper(StackOverflows选择的ORM)。它是非常轻量级的ORM,它提供了一个简单的查询数据库的接口。虽然它允许您将结果映射到Class,但它也允许完全动态的查询。
由于它返回IEnumerable<dynamic>
,您不必担心结果类型的差异。调用搜索表单的表单知道它需要访问哪些属性。
using (var db = new SqlConnection(connectionString))
{
db.Open();
IEnumerable<dyanmic> results = db.Query("select * from table");
return results;
}
答案 2 :(得分:0)
我建议实现观察者设计模式。
您可以使用IObserver和IObservable接口,并提供可扩展的解决方案。
要了解有关观察者设计模式的更多信息,请仔细阅读
http://www.dofactory.com/Patterns/PatternObserver.aspx
http://msdn.microsoft.com/en-us/library/ee817669.aspx
http://msdn.microsoft.com/en-us/library/dd990377(v=vs.110).aspx
http://msdn.microsoft.com/en-us/library/dd783449(v=vs.110).aspx
这是一个非常原始的例子:
public class SearchData
{
private DataTable _result = new DataTable();
public DataTable Result {
get { return _result; }
private set { _result = value; }
}
// simple, provides the search data
public SearchData Search()
{
// use your own code to search, below code is only for a test purpose
_result.Columns.Add(new DataColumn("Id", typeof(int)));
_result.Columns.Add(new DataColumn("Name", typeof(string)));
DataRow row = _result.NewRow();
row["Id"] = 1;
row["Name"] = "Some Name";
_result.Rows.Add(row);
return this;
}
}
IObservable:
// Search Form : the observable responsible for sending search data back to other forms
public partial class SearchForm : Form, IObservable<SearchData>
{
private List<IObserver<SearchData>> _observers;
public SearchForm()
{
_observers = new List<IObserver<SearchData>>();
InitializeComponent();
}
public IDisposable Subscribe(IObserver<SearchData> observer)
{
if (!_observers.Contains(observer))
_observers.Add(observer);
return new Unsubscriber(_observers, observer);
}
private void btnSearch_Click(object sender, EventArgs e)
{
Search();
}
private void Search()
{
SearchData newSearch = new SearchData();
SearchData searchValue = newSearch.Search();
foreach (var observer in _observers)
{
if (searchValue == null)
observer.OnError(new Exception("pass some expection"));
else
observer.OnNext(searchValue);
}
}
}
IObserver:
public partial class Form1 : Form, IObserver<SearchData>
{
private IDisposable _unsubscriber;
SearchForm _frm;
public Form1()
{
InitializeComponent();
_frm = new SearchForm();
this.Subscribe(_frm);
}
private void button1_Click(object sender, EventArgs e)
{
_frm.Show();
}
public void OnCompleted()
{
this.Unsubscribe();
}
public void OnError(Exception error)
{
throw error;
}
public void OnNext(SearchData value)
{
searchDataGrid.DataSource = value.Result;
}
public virtual void Unsubscribe()
{
_unsubscriber.Dispose();
}
public virtual void Subscribe(IObservable<SearchData> provider)
{
if (provider != null)
_unsubscriber = provider.Subscribe(this);
}
}
请注意,这是一个非常快速和肮脏的例子,但是给出了一个很好的起点。 我还没有正确使用异常处理,不要忘记使用它。
通过这种方式,您可以添加许多(调用)表单并向SearchForm注册并获取结果。我一次又一次地创建搜索表单。您可以将其设置为全局并在整个应用程序中使用它而无需重新创建它。
哎呀,忘了添加非订阅者 公共类Unsubscriber:IDisposable { 私人清单&gt; _observers; private IObserver _observer;
public Unsubscriber(List<IObserver<SearchData>> observers, IObserver<SearchData> observer)
{
this._observers = observers;
this._observer = observer;
}
public void Dispose()
{
if (_observer != null && _observers.Contains(_observer))
_observers.Remove(_observer);
}
}