We are developing application using WPF,material design and MS-Access 2007 as Back End. Now we are facing problem of application slow down while opening single view ,that particular view have 16 combo's which fill. It take 7 seconds for process, following code used for bind combo box item source
List<ComboBind> values = new List<ComboBind>();
try
{
using (var oleDbCommand = new OleDbCommand())
{
oleDbCommand.CommandText = query ;
oleDbCommand.Connection = Connection.con;
var sql = query;
var oleDbDataReader = oleDbCommand.ExecuteReader();
while (oleDbDataReader.Read())
{
ComboBind b = new ComboBind();
b.id = oleDbDataReader[0].ToString().ToInt();
b.name = oleDbDataReader[1].ToString();
values.Add(b);
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
It looks like you are trying to load data in UI thread during view initialization and this is the reason of the issue. Either do loading of data in background thread or do it before opening the view.
Simple code snippet for loading data in separate task:
//Might be your view code behind or
//ViewModel if you are using MVVM
public class ViewCodeBehind
{
public List<ComboBind> ComboItems { get; set; }
public void Initialize()
{
//start bacground task for data loading
var comboQuery = "select *from data";
Task.Run(() => LoadItems(comboQuery));
}
public void LoadItems(string query)
{
List<ComboBind> values = new List<ComboBind>();
try
{
using (var oleDbCommand = new OleDbCommand())
{
oleDbCommand.CommandText = query;
oleDbCommand.Connection = Connection.con;
var sql = query;
var oleDbDataReader = oleDbCommand.ExecuteReader();
while (oleDbDataReader.Read())
{
ComboBind b = new ComboBind();
b.id = oleDbDataReader[0].ToString().ToInt();
b.name = oleDbDataReader[1].ToString();
values.Add(b);
}
}
//use dispatcher to pass data back to UI thread
System.Windows.Threading.Dispatcher.CurrentDispatcher.BeginInvoke(
new Action(() =>
{
ComboItems = values;
}));
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
Related
I've made a windows forms app that imports data to my sql database.
This is how data can look in the database
Problem If I now want to import more data and say that there is a entry in the new data that I'm importing that already exist in my sql data table, that is, an entry with the exact same value that already exist in my sql table. Then I would like to not import this particular entry and move on the next one.
The code I'm using for this is paintstakingly slow and I would like to find a quicker/better way of doing this. Please see #region DAX for the code and the try catch.
Here is the code that executes on my button click for import :)
Thanks!
private void dataImportButton_Click(object sender, EventArgs e)
{
Cursor.Current = Cursors.WaitCursor;
int candle = 0;
string candleStick = "";
foreach (var item in checkedListBox1.CheckedItems)
{
candleStick += item.ToString();
}
Regex regex = new Regex(#"\d*");
Match match = regex.Match(candleStick);
if (match.Success)
{
candle = Convert.ToInt32(match.Value);
}
string nameOfTable = string.Empty;
foreach (var item in checkedListBox2.CheckedItems)
{
nameOfTable += item.ToString();
}
string filePath = textBox1.Text;
var listaNerladdat = System.IO.File.ReadLines(filePath);
if (nameOfTable == "DAX")
#region DAX
{
foreach (var item in listaNerladdat)
{
var splitLista = item.Split(';').ToList();
if (splitLista.Count < 5)
continue;
var tmpSplitInfo = new DaxSuperTabell();
DateTime tmpDate;
if (DateTime.TryParse(splitLista[0], out tmpDate))
tmpSplitInfo.TimeStampMVCR = tmpDate;
double tmpX;
if (Double.TryParse(splitLista[1].Replace('.', ','), out tmpX))
tmpSplitInfo.HighPriceMVCR = tmpX;
if (Double.TryParse(splitLista[2].Replace('.', ','), out tmpX))
tmpSplitInfo.LowPriceMVCR = tmpX;
if (Double.TryParse(splitLista[3].Replace('.', ','), out tmpX))
tmpSplitInfo.OpenPriceMVCR = tmpX;
if (Double.TryParse(splitLista[4].Replace('.', ','), out tmpX))
tmpSplitInfo.ClosePriceMVCR = tmpX;
tmpSplitInfo.CandleStick = candle;
try{
_context.DaxSuperTabell.AddRange(tmpSplitInfo);
_context.SaveChanges();
}
catch{MessageBox.Show("This entry is a double")}
}
}
#endregion
}
I want to save the contents of a SelectedItem or Item's from a ComboBox as well as DataGrid Column Order so as retain the information when the application is reopened.
Initially I am using the below code for saving the data as long as the application is open:
App.Current.Properties[1] = SelectedDataSetList;
App.Current.Properties[2] = SelectedModuleList;
App.Current.Properties[0] = SelectedContentSet;
SelectedDataSetList is bound to a ComboBox:
<dxe:ComboBoxEdit Text="SCOPE" x:Name="ContentSetCombobox" Grid.Column="1" Height="25" IncrementalFiltering="True" ItemsSource="{Binding ContentSetList}" DisplayMember="Name" AllowUpdateTwoWayBoundPropertiesOnSynchronization="False" SelectedItem="{Binding SelectedContentSet,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" >
But, I was unable to store the information in a Chache memory for retrieving even if the application is closed and opened again.
Is there any way to do this without using an external file like .xml?
If you're looking to save to IsolatedStorage you can use this class I've put together (see below). It's not perfect and will fail if you try to save a type that isn't marked as Serializable but it's good enough for casual use. I've left exception handling as an exercise for the OP.
public class IsolatedStorageManager
{
public void Save<T>(T item, string key)
{
var isf = IsolatedStorageFile.GetStore(IsolatedStorageScope.User | IsolatedStorageScope.Assembly, null, null);
using (var writeStream = new IsolatedStorageFileStream(key, FileMode.Create, isf))
{
Serialise(item, writeStream);
}
}
public T Open<T>(string key)
{
var isf = IsolatedStorageFile.GetStore(IsolatedStorageScope.User | IsolatedStorageScope.Assembly, null, null);
using (var readStream = new IsolatedStorageFileStream(key, FileMode.Open, isf))
{
var item = Deserialise<T>(readStream);
return item;
}
}
private Stream Serialise<T>(T item, Stream stream)
{
var formatter = new BinaryFormatter();
formatter.Serialize(stream, item);
return stream;
}
private T Deserialise<T>(Stream stream)
{
var formatter = new BinaryFormatter();
var item = formatter.Deserialize(stream);
return (T) item;
}
}
Saving classes and datasets is demonstrated in the test fixture below.
[TestFixture]
public class IsolatedStorageManagerTestFixture
{
private IsolatedStorageManager _underTest;
private const string SaveFileKey = "TestSaveFileKey";
[SetUp]
public void SetUp()
{
_underTest = new IsolatedStorageManager();
}
[Test]
public void TestSavingDataset()
{
var tableName = "TestTable";
var ds = new DataSet();
ds.Tables.Add(new DataTable(tableName));
_underTest.Save(ds, SaveFileKey);
var saved = _underTest.Open<DataSet>(SaveFileKey);
Assert.That(saved.Tables.Count==1);
Assert.That(saved.Tables[0].TableName == tableName);
}
[Test]
public void TestSavingClass()
{
var list = new ArrayList {"Hello", new DataTable(), 2};
_underTest.Save(list,SaveFileKey);
var saved = _underTest.Open<ArrayList>(SaveFileKey);
Assert.That(saved.Count==3);
Assert.That(string.Equals((string)saved[0], "Hello"));
Assert.That(list[1] is DataTable);
Assert.That((int)list[2] == 2);
}
}
I have a datagrid and a refresh button. I want to refresh data when I click on it but it won't. I also deleted all the rows from SQL Server but the data is still there.
Here's my button code:
Student std = new Student();
dataGridView1.DataSource = false;
dataGridView1.DataSource = std.List();
and here's is my List() function:
public DataTable List()
{
try
{
sdl.Command.CommandText = this.GetType().Name + "_List";
var dt = new DataTable();
dt.Clear();
SqlDataAdapter sda = new SqlDataAdapter(sdl.Command);
sda.Fill(dt);
return dt;
}
catch (Exception ex)
{
this.Message = ex.Message;
throw;
}
finally
{
if (sdl.Connection.State == System.Data.ConnectionState.Open)
{
sdl.Connection.Close();
}
}
}
I think you just need below line
dataGridView1.DataBind();
Assuming that you are using Windows Forms, to refresh the datagrid contents, assuming that std.List() works and actually gets new data you could try:
this.dataGridView1.EndEdit(); //end current edits if you allow this (optional)
this.dataGridView1.DataSource = null; //reset datasource binding
this.dataGridView1.DataSource = std.List();
This topic has been debated heavily in the past e.g. see:Refresh dgv.
DataSet ds = new DataSet();
ds.Tables.Add(List());
DataGridView1.DataSource = ds.Tables[0].DefaultView;
I'm trying to establish a master-detail relation between two DataGridView.
I have an EntityModel with two entities connected by "ClientComissions" Association.
They were generated from an existing DB, and have Navigation Properties, that work well.
Proof (console app using mentioned EntityModel):
using (var context = new MnxEntities())
{
Client client = context.Clients.FirstOrDefault();
// profiler: "SELECT TOP (1) ... FROM [Clients] AS [c]" - Ok!
Console.WriteLine("Client: {0}", client.Name);
foreach (Comission comission in client.NavComissions)
// profiler: "SELECT ... FROM [Comissions] WHERE [StateCode] = '20971504'" - Ok!
{
Console.WriteLine("Agreement number: {0}", comission.Dog_Num);
}
}
But I can't bind two DataGridViews in a master-detail manner on windows form:
private void tabComissions_Enter(object sender, EventArgs e)
{
using (var context = new MnxEntities())
{
clientDataGridView.DataSource = context.Clients;
comissionsDataGridView.DataSource = clientDataGridView.DataSource;
comissionsDataGridView.DataMember = "WHAT SHOULD BE HERE?";
}
}
I know there is a BindingContext, that must do all the job using CurrencyManager, with no hand-written code needed.
I've stuck here for to much time. Help please.
UPD:
private void AnswerFromStackRefactored()
{
using (var context = new MnxEntities())
{
clientBindingSource.DataSource = context;
clientBindingSource.DataMember = "Clients";
navComissionsBindingSource.DataSource = clientBindingSource;
navComissionsBindingSource.DataMember = "NavComissions";
}
}
this code loads Comissions only once, for the first client in grid.
But when I change Current row in Clients Grid there is no more query to DB and navComissionsGrid always show comission for the first client. :(
Pull two ListViews on a Form and name them as lstcategory and lstProduct respectively. Then copy the code below [its very simple]. You may apply the same concept to your problem.
public partial class MasterDetail : Form
{
public MasterDetail()
{
InitializeComponent();
}
private BindingManagerBase categoryBinding;
private DataSet ds;
private void MasterDetail_Load(object sender, EventArgs e)
{
ds = GetCategoriesAndProducts();
// Bind the lists to different tables.
lstCategory.DataSource = ds.Tables["Categories"];
lstCategory.DisplayMember = "CategoryName";
lstProduct.DataSource = ds.Tables["Products"];
lstProduct.DisplayMember = "ProductName";
// Track the binding context and handle position changing.
categoryBinding = this.BindingContext[ds.Tables["Categories"]];
categoryBinding.PositionChanged += new EventHandler(Binding_PositionChanged);
// Update child table at startup.
UpdateProducts();
}
private void Binding_PositionChanged(object sender, System.EventArgs e)
{
UpdateProducts();
}
private void UpdateProducts()
{
string filter;
DataRow selectedRow;
// Find the current category row.
selectedRow = ds.Tables["Categories"].Rows[categoryBinding.Position];
// Create a filter expression using its CategoryID.
filter = "CategoryID='" + selectedRow["CategoryID"].ToString() + "'";
// Modify the view onto the product table.
ds.Tables["Products"].DefaultView.RowFilter = filter;
}
public DataSet GetCategoriesAndProducts()
{
DataTable category = new DataTable("Categories");
category.Columns.Add("CategoryID");
category.Columns.Add("CategoryName");
category.Rows.Add(new object[] { "1", "Food" });
category.Rows.Add(new object[] { "2", "Beverage" });
DataTable product = new DataTable("Products");
product.Columns.Add("CategoryID");
product.Columns.Add("ProductName");
product.Rows.Add(new object[] { "1", "Rice" });
product.Rows.Add(new object[] { "1", "Pasta" });
product.Rows.Add(new object[] { "2", "Cola" });
product.Rows.Add(new object[] { "2", "Coffee" });
product.Rows.Add(new object[] { "2", "Tea" });
DataSet ds = new DataSet();
ds.Tables.Add(category);
ds.Tables.Add(product);
// Set up a relation between these tables (optional).
DataRelation relCategoryProduct = new DataRelation("CategoryProduct",
ds.Tables["Categories"].Columns["CategoryID"],
ds.Tables["Products"].Columns["CategoryID"]);
ds.Relations.Add(relCategoryProduct);
return ds;
}
}
I have a requirement in which I have to show the number of documents uploaded by a user in all the lists and libraries in a SharePoint site in a Silverlight webppart.
How much ever I try I keep getting the error "The property or field has not been initialized. It has not been requested or the request has not been executed. It may need to be explicitly requested." This is my coding
public void displayCount()
{
foreach (string list in lists)
{
web = ctx.Web;
ctx.Load(web);
List list = web.Lists.GetByTitle(list);
ctx.Load(list);
CamlQuery camlQuery = new CamlQuery();
camlQuery.ViewXml = "<View/>";
listItems = list.GetItems(camlQuery);
ctx.Load(listItems);
ctx.ExecuteQueryAsync(Success, null);
}
}
private void Success(object sender, ClientRequestSucceededEventArgs args)
{
UpdateUIMethod updateUI = DisplayInfo;
this.Dispatcher.BeginInvoke(updateUI);
}
private void DisplayInfo()
{
try
{
TextBlock tb = new TextBlock();
tb.Text = Convert.ToString(listItems.Count);
LayoutRoot.Children.Add(tb);
}
catch (Exception ex)
{
TextBlock tb = new TextBlock();
tb.Text = ex.Message;
LayoutRoot.Children.Add(tb);
}
}
see http://www.sharepointqanda.com/2010/10/how-to-get-listitems-count-in-all-the-lists-of-a-sharepoint-site-through-silverlight-client-object-model/