wpf textbox content freezes ui on load
I started coding my first WPF app and I'm having trouble with a textbox that displays some system info (cpu, memory, disk usage, mac address, etc.).
My apps has navigation between two pages and the said textbox is on one of the pages. The textbox's content is retrieved via WMI queries.
The issue I have noticed is that while navigating to tha page with the textbox it freezes the UI for about two seconds before going to and display the page.
I'm a newbie and my best guess is that eighter the WMI queries(could be badly coded too) are doing that or I'm loading the content in the textbox wrongfully.
An example of how my queries are constructed
public string getCPU()
{
ManagementObjectSearcher searcher = new
ManagementObjectSearcher("root\CIMV2", "SELECT * FROM Win32_Processor");
StringBuilder sb = new StringBuilder();
foreach (ManagementObject wmi in searcher.Get())
{
try
{
sb.Append("Processor: " + wmi.GetPropertyValue("Name").ToString() + Environment.NewLine);
}
catch
{
return sb.ToString();
}
}
return sb.ToString();
}
public string getRAMsize()
{
ManagementClass mc = new ManagementClass("Win32_ComputerSystem");
ManagementObjectCollection moc = mc.GetInstances();
foreach (ManagementObject item in moc)
{
return Convert.ToString(Math.Round(Convert.ToDouble(item.Properties["TotalPhysicalMemory"].Value) / (1024 * 1024 * 1024), 0)) + " GB";
}
return "RAMsize";
}
And this is what I use to retrieve the data in the textbox:
private void TextBox1_Loaded(object sender, RoutedEventArgs e)
{
TextBox1.Text = getCPU();
TextBox1.Text += "Memory: " + getRAMsize() + Environment.NewLine;
TextBox1.Text += "Free Space: " + GetTotalFreeSpace(sysdrive) + " GB" + Environment.NewLine;
if (Is64BitSystem)
{
TextBox1.Text += getOS() + " 64bit" + Environment.NewLine;
}
else
{
TextBox1.Text += getOS() + " 32 Bit" + Environment.NewLine;
}
TextBox1.Text += "MAC Address : " + System.Text.RegularExpressions.Regex.Replace(GetMacAddress().ToString(), ".{2}", "$0 ") + Environment.NewLine;
TextBox1.Text += av();
}
My question is what am I doing wrong and how can I get around with it. In my mind , if the queries are constructed correctly, it would be because they are done again and again everytime the textbox is loaded (on navigation or at startup) and maybe If I could get it to load only once and remember those values(since most of the data should stay the same).
But as I said I'm a noob and any help will be greatly appreciated.
Thanks in advance
c# wpf user-interface textbox
add a comment |
I started coding my first WPF app and I'm having trouble with a textbox that displays some system info (cpu, memory, disk usage, mac address, etc.).
My apps has navigation between two pages and the said textbox is on one of the pages. The textbox's content is retrieved via WMI queries.
The issue I have noticed is that while navigating to tha page with the textbox it freezes the UI for about two seconds before going to and display the page.
I'm a newbie and my best guess is that eighter the WMI queries(could be badly coded too) are doing that or I'm loading the content in the textbox wrongfully.
An example of how my queries are constructed
public string getCPU()
{
ManagementObjectSearcher searcher = new
ManagementObjectSearcher("root\CIMV2", "SELECT * FROM Win32_Processor");
StringBuilder sb = new StringBuilder();
foreach (ManagementObject wmi in searcher.Get())
{
try
{
sb.Append("Processor: " + wmi.GetPropertyValue("Name").ToString() + Environment.NewLine);
}
catch
{
return sb.ToString();
}
}
return sb.ToString();
}
public string getRAMsize()
{
ManagementClass mc = new ManagementClass("Win32_ComputerSystem");
ManagementObjectCollection moc = mc.GetInstances();
foreach (ManagementObject item in moc)
{
return Convert.ToString(Math.Round(Convert.ToDouble(item.Properties["TotalPhysicalMemory"].Value) / (1024 * 1024 * 1024), 0)) + " GB";
}
return "RAMsize";
}
And this is what I use to retrieve the data in the textbox:
private void TextBox1_Loaded(object sender, RoutedEventArgs e)
{
TextBox1.Text = getCPU();
TextBox1.Text += "Memory: " + getRAMsize() + Environment.NewLine;
TextBox1.Text += "Free Space: " + GetTotalFreeSpace(sysdrive) + " GB" + Environment.NewLine;
if (Is64BitSystem)
{
TextBox1.Text += getOS() + " 64bit" + Environment.NewLine;
}
else
{
TextBox1.Text += getOS() + " 32 Bit" + Environment.NewLine;
}
TextBox1.Text += "MAC Address : " + System.Text.RegularExpressions.Regex.Replace(GetMacAddress().ToString(), ".{2}", "$0 ") + Environment.NewLine;
TextBox1.Text += av();
}
My question is what am I doing wrong and how can I get around with it. In my mind , if the queries are constructed correctly, it would be because they are done again and again everytime the textbox is loaded (on navigation or at startup) and maybe If I could get it to load only once and remember those values(since most of the data should stay the same).
But as I said I'm a noob and any help will be greatly appreciated.
Thanks in advance
c# wpf user-interface textbox
add a comment |
I started coding my first WPF app and I'm having trouble with a textbox that displays some system info (cpu, memory, disk usage, mac address, etc.).
My apps has navigation between two pages and the said textbox is on one of the pages. The textbox's content is retrieved via WMI queries.
The issue I have noticed is that while navigating to tha page with the textbox it freezes the UI for about two seconds before going to and display the page.
I'm a newbie and my best guess is that eighter the WMI queries(could be badly coded too) are doing that or I'm loading the content in the textbox wrongfully.
An example of how my queries are constructed
public string getCPU()
{
ManagementObjectSearcher searcher = new
ManagementObjectSearcher("root\CIMV2", "SELECT * FROM Win32_Processor");
StringBuilder sb = new StringBuilder();
foreach (ManagementObject wmi in searcher.Get())
{
try
{
sb.Append("Processor: " + wmi.GetPropertyValue("Name").ToString() + Environment.NewLine);
}
catch
{
return sb.ToString();
}
}
return sb.ToString();
}
public string getRAMsize()
{
ManagementClass mc = new ManagementClass("Win32_ComputerSystem");
ManagementObjectCollection moc = mc.GetInstances();
foreach (ManagementObject item in moc)
{
return Convert.ToString(Math.Round(Convert.ToDouble(item.Properties["TotalPhysicalMemory"].Value) / (1024 * 1024 * 1024), 0)) + " GB";
}
return "RAMsize";
}
And this is what I use to retrieve the data in the textbox:
private void TextBox1_Loaded(object sender, RoutedEventArgs e)
{
TextBox1.Text = getCPU();
TextBox1.Text += "Memory: " + getRAMsize() + Environment.NewLine;
TextBox1.Text += "Free Space: " + GetTotalFreeSpace(sysdrive) + " GB" + Environment.NewLine;
if (Is64BitSystem)
{
TextBox1.Text += getOS() + " 64bit" + Environment.NewLine;
}
else
{
TextBox1.Text += getOS() + " 32 Bit" + Environment.NewLine;
}
TextBox1.Text += "MAC Address : " + System.Text.RegularExpressions.Regex.Replace(GetMacAddress().ToString(), ".{2}", "$0 ") + Environment.NewLine;
TextBox1.Text += av();
}
My question is what am I doing wrong and how can I get around with it. In my mind , if the queries are constructed correctly, it would be because they are done again and again everytime the textbox is loaded (on navigation or at startup) and maybe If I could get it to load only once and remember those values(since most of the data should stay the same).
But as I said I'm a noob and any help will be greatly appreciated.
Thanks in advance
c# wpf user-interface textbox
I started coding my first WPF app and I'm having trouble with a textbox that displays some system info (cpu, memory, disk usage, mac address, etc.).
My apps has navigation between two pages and the said textbox is on one of the pages. The textbox's content is retrieved via WMI queries.
The issue I have noticed is that while navigating to tha page with the textbox it freezes the UI for about two seconds before going to and display the page.
I'm a newbie and my best guess is that eighter the WMI queries(could be badly coded too) are doing that or I'm loading the content in the textbox wrongfully.
An example of how my queries are constructed
public string getCPU()
{
ManagementObjectSearcher searcher = new
ManagementObjectSearcher("root\CIMV2", "SELECT * FROM Win32_Processor");
StringBuilder sb = new StringBuilder();
foreach (ManagementObject wmi in searcher.Get())
{
try
{
sb.Append("Processor: " + wmi.GetPropertyValue("Name").ToString() + Environment.NewLine);
}
catch
{
return sb.ToString();
}
}
return sb.ToString();
}
public string getRAMsize()
{
ManagementClass mc = new ManagementClass("Win32_ComputerSystem");
ManagementObjectCollection moc = mc.GetInstances();
foreach (ManagementObject item in moc)
{
return Convert.ToString(Math.Round(Convert.ToDouble(item.Properties["TotalPhysicalMemory"].Value) / (1024 * 1024 * 1024), 0)) + " GB";
}
return "RAMsize";
}
And this is what I use to retrieve the data in the textbox:
private void TextBox1_Loaded(object sender, RoutedEventArgs e)
{
TextBox1.Text = getCPU();
TextBox1.Text += "Memory: " + getRAMsize() + Environment.NewLine;
TextBox1.Text += "Free Space: " + GetTotalFreeSpace(sysdrive) + " GB" + Environment.NewLine;
if (Is64BitSystem)
{
TextBox1.Text += getOS() + " 64bit" + Environment.NewLine;
}
else
{
TextBox1.Text += getOS() + " 32 Bit" + Environment.NewLine;
}
TextBox1.Text += "MAC Address : " + System.Text.RegularExpressions.Regex.Replace(GetMacAddress().ToString(), ".{2}", "$0 ") + Environment.NewLine;
TextBox1.Text += av();
}
My question is what am I doing wrong and how can I get around with it. In my mind , if the queries are constructed correctly, it would be because they are done again and again everytime the textbox is loaded (on navigation or at startup) and maybe If I could get it to load only once and remember those values(since most of the data should stay the same).
But as I said I'm a noob and any help will be greatly appreciated.
Thanks in advance
c# wpf user-interface textbox
c# wpf user-interface textbox
edited Nov 22 at 15:10
asked Nov 22 at 13:27
erma86
1115
1115
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
After checking each and every query I found out that the getCPU one is causing a delay in the load.
I replaced it with a Registry.GetValue, wich is very fast.
Thanks to Sebastian L, because altough his code didn't work for me it put me on the right path and I was able to adapt own code with a backgroundworker to avoid UI freeze of any kind
my working code:
private void TextBox1_Loaded(object sender, RoutedEventArgs e)
{
BackgroundWorker bw = new BackgroundWorker();
bw.WorkerReportsProgress = true;
bw.DoWork += new DoWorkEventHandler(delegate (object o, DoWorkEventArgs args)
{
});
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(delegate (object o, RunWorkerCompletedEventArgs args)
{
TextBox1.Text = (string)Registry.GetValue(@"HKEY_LOCAL_MACHINEHARDWAREDESCRIPTIONSystemCentralProcessor", "ProcessorNameString", null) + Environment.NewLine;
TextBox1.Text += "Memory: " + getRAMsize() + Environment.NewLine;
TextBox1.Text += "Free Space: " + GetTotalFreeSpace(sysdrive) + " GB" + Environment.NewLine;
if (Is64BitSystem)
{
TextBox1.Text += getOS() + " 64bit" + Environment.NewLine;
}
else
{
TextBox1.Text += getOS() + " 32 Bit" + Environment.NewLine;
}
TextBox1.Text += "MAC Address : " + System.Text.RegularExpressions.Regex.Replace(GetMacAddress().ToString(), ".{2}", "$0 ") + Environment.NewLine;
TextBox1.Text += av();
});
bw.RunWorkerAsync();
}
add a comment |
You are aquiring your data in the UI Thread.
You should load the data in the background thread and then, since you use wpf, binding the textbox text to a variable.
Example (This code is Copy'n'Paste ready):
// INotifyPropertyChanged is an Interface which enables binding of Properties in your window
public partial class MainWindow : Window, INotifyPropertyChanged
{
private string _systemInformation;
// Stub (works actually)
private bool is64BitSystem = (IntPtr.Size == 8);
// Stub
private string sysdrive = "YOLO\:";
public MainWindow()
{
InitializeComponent();
// Set Datacontext normally set to a viewmodel but ther is none in this code
this.DataContext = this;
// The Backgroundworker does things in the background (nonblocking)
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += DoItButDontInterruptMeDuh;
bw.RunWorkerAsync();
}
public event PropertyChangedEventHandler PropertyChanged;
public string SystemInformation { get => _systemInformation; set => _systemInformation = value; }
//Stub
public string getCPU()
{
return "Fancy CPU";
}
//Stub
public string getRAMsize()
{
return "1 PB";
}
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
//Stub
private string av()
{
return "Whatever av means.";
}
private void DoItButDontInterruptMeDuh(object sender, DoWorkEventArgs e)
{
// Simulate loading time
Thread.Sleep(5000);
SystemInformation = getCPU();
SystemInformation += "Memory: " + getRAMsize() + Environment.NewLine;
SystemInformation += "Free Space: " + GetTotalFreeSpace(sysdrive) + " GB" + Environment.NewLine;
if (is64BitSystem)
{
SystemInformation += getOS() + " 64bit" + Environment.NewLine;
}
else
{
SystemInformation += getOS() + " 32 Bit" + Environment.NewLine;
}
SystemInformation += "MAC Address : " + System.Text.RegularExpressions.Regex.Replace(GetMacAddress().ToString(), ".{2}", "$0 ") + Environment.NewLine;
SystemInformation += av();
OnPropertyChanged("SystemInformation");
}
//Stub
private object GetMacAddress()
{
return "Macintoshstreet 1234";
}
//Stub
private string getOS()
{
return "Cool OS";
}
//Stub
private string GetTotalFreeSpace(object sysdrive)
{
return "0";
}
}
and in the .xaml:
<TextBox Text={Binding Path=SystemInformation}/>
Your code doesn't show how to run the tasks in the background thread also you should point out that any attempt to manipulate UI element from background thread will result in an exception being thrown. As the UI elements are NOT thread safe. Also your xaml is not correct.
– XAMlMAX
Nov 22 at 14:26
Please, more noob friendly. Do I have to create a new class called SomeWindow (or SysInfo) ? what is InitWhatever(); supposed to be(same doesn't exist in current context)? NotifyOfPropertyChange(() => systemInformation); throws exception : doesn't exist in current context
– erma86
Nov 22 at 14:44
edited my answer accordingly
– Sebastian L
Nov 22 at 15:19
many thanks, but still got 1 exception : Type 'MainWindow' already defines a member called '.ctor' with the same parameter types
– erma86
Nov 22 at 15:46
probabily my bad since I pasted the code in a new class file and that's why it was throwin that exception. Moved the code in the MainWindow.cs file and the exception is gone...still textbox doesn't load the content.
– erma86
Nov 22 at 16:13
|
show 4 more comments
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53432038%2fwpf-textbox-content-freezes-ui-on-load%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
After checking each and every query I found out that the getCPU one is causing a delay in the load.
I replaced it with a Registry.GetValue, wich is very fast.
Thanks to Sebastian L, because altough his code didn't work for me it put me on the right path and I was able to adapt own code with a backgroundworker to avoid UI freeze of any kind
my working code:
private void TextBox1_Loaded(object sender, RoutedEventArgs e)
{
BackgroundWorker bw = new BackgroundWorker();
bw.WorkerReportsProgress = true;
bw.DoWork += new DoWorkEventHandler(delegate (object o, DoWorkEventArgs args)
{
});
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(delegate (object o, RunWorkerCompletedEventArgs args)
{
TextBox1.Text = (string)Registry.GetValue(@"HKEY_LOCAL_MACHINEHARDWAREDESCRIPTIONSystemCentralProcessor", "ProcessorNameString", null) + Environment.NewLine;
TextBox1.Text += "Memory: " + getRAMsize() + Environment.NewLine;
TextBox1.Text += "Free Space: " + GetTotalFreeSpace(sysdrive) + " GB" + Environment.NewLine;
if (Is64BitSystem)
{
TextBox1.Text += getOS() + " 64bit" + Environment.NewLine;
}
else
{
TextBox1.Text += getOS() + " 32 Bit" + Environment.NewLine;
}
TextBox1.Text += "MAC Address : " + System.Text.RegularExpressions.Regex.Replace(GetMacAddress().ToString(), ".{2}", "$0 ") + Environment.NewLine;
TextBox1.Text += av();
});
bw.RunWorkerAsync();
}
add a comment |
After checking each and every query I found out that the getCPU one is causing a delay in the load.
I replaced it with a Registry.GetValue, wich is very fast.
Thanks to Sebastian L, because altough his code didn't work for me it put me on the right path and I was able to adapt own code with a backgroundworker to avoid UI freeze of any kind
my working code:
private void TextBox1_Loaded(object sender, RoutedEventArgs e)
{
BackgroundWorker bw = new BackgroundWorker();
bw.WorkerReportsProgress = true;
bw.DoWork += new DoWorkEventHandler(delegate (object o, DoWorkEventArgs args)
{
});
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(delegate (object o, RunWorkerCompletedEventArgs args)
{
TextBox1.Text = (string)Registry.GetValue(@"HKEY_LOCAL_MACHINEHARDWAREDESCRIPTIONSystemCentralProcessor", "ProcessorNameString", null) + Environment.NewLine;
TextBox1.Text += "Memory: " + getRAMsize() + Environment.NewLine;
TextBox1.Text += "Free Space: " + GetTotalFreeSpace(sysdrive) + " GB" + Environment.NewLine;
if (Is64BitSystem)
{
TextBox1.Text += getOS() + " 64bit" + Environment.NewLine;
}
else
{
TextBox1.Text += getOS() + " 32 Bit" + Environment.NewLine;
}
TextBox1.Text += "MAC Address : " + System.Text.RegularExpressions.Regex.Replace(GetMacAddress().ToString(), ".{2}", "$0 ") + Environment.NewLine;
TextBox1.Text += av();
});
bw.RunWorkerAsync();
}
add a comment |
After checking each and every query I found out that the getCPU one is causing a delay in the load.
I replaced it with a Registry.GetValue, wich is very fast.
Thanks to Sebastian L, because altough his code didn't work for me it put me on the right path and I was able to adapt own code with a backgroundworker to avoid UI freeze of any kind
my working code:
private void TextBox1_Loaded(object sender, RoutedEventArgs e)
{
BackgroundWorker bw = new BackgroundWorker();
bw.WorkerReportsProgress = true;
bw.DoWork += new DoWorkEventHandler(delegate (object o, DoWorkEventArgs args)
{
});
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(delegate (object o, RunWorkerCompletedEventArgs args)
{
TextBox1.Text = (string)Registry.GetValue(@"HKEY_LOCAL_MACHINEHARDWAREDESCRIPTIONSystemCentralProcessor", "ProcessorNameString", null) + Environment.NewLine;
TextBox1.Text += "Memory: " + getRAMsize() + Environment.NewLine;
TextBox1.Text += "Free Space: " + GetTotalFreeSpace(sysdrive) + " GB" + Environment.NewLine;
if (Is64BitSystem)
{
TextBox1.Text += getOS() + " 64bit" + Environment.NewLine;
}
else
{
TextBox1.Text += getOS() + " 32 Bit" + Environment.NewLine;
}
TextBox1.Text += "MAC Address : " + System.Text.RegularExpressions.Regex.Replace(GetMacAddress().ToString(), ".{2}", "$0 ") + Environment.NewLine;
TextBox1.Text += av();
});
bw.RunWorkerAsync();
}
After checking each and every query I found out that the getCPU one is causing a delay in the load.
I replaced it with a Registry.GetValue, wich is very fast.
Thanks to Sebastian L, because altough his code didn't work for me it put me on the right path and I was able to adapt own code with a backgroundworker to avoid UI freeze of any kind
my working code:
private void TextBox1_Loaded(object sender, RoutedEventArgs e)
{
BackgroundWorker bw = new BackgroundWorker();
bw.WorkerReportsProgress = true;
bw.DoWork += new DoWorkEventHandler(delegate (object o, DoWorkEventArgs args)
{
});
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(delegate (object o, RunWorkerCompletedEventArgs args)
{
TextBox1.Text = (string)Registry.GetValue(@"HKEY_LOCAL_MACHINEHARDWAREDESCRIPTIONSystemCentralProcessor", "ProcessorNameString", null) + Environment.NewLine;
TextBox1.Text += "Memory: " + getRAMsize() + Environment.NewLine;
TextBox1.Text += "Free Space: " + GetTotalFreeSpace(sysdrive) + " GB" + Environment.NewLine;
if (Is64BitSystem)
{
TextBox1.Text += getOS() + " 64bit" + Environment.NewLine;
}
else
{
TextBox1.Text += getOS() + " 32 Bit" + Environment.NewLine;
}
TextBox1.Text += "MAC Address : " + System.Text.RegularExpressions.Regex.Replace(GetMacAddress().ToString(), ".{2}", "$0 ") + Environment.NewLine;
TextBox1.Text += av();
});
bw.RunWorkerAsync();
}
answered Nov 23 at 23:31
erma86
1115
1115
add a comment |
add a comment |
You are aquiring your data in the UI Thread.
You should load the data in the background thread and then, since you use wpf, binding the textbox text to a variable.
Example (This code is Copy'n'Paste ready):
// INotifyPropertyChanged is an Interface which enables binding of Properties in your window
public partial class MainWindow : Window, INotifyPropertyChanged
{
private string _systemInformation;
// Stub (works actually)
private bool is64BitSystem = (IntPtr.Size == 8);
// Stub
private string sysdrive = "YOLO\:";
public MainWindow()
{
InitializeComponent();
// Set Datacontext normally set to a viewmodel but ther is none in this code
this.DataContext = this;
// The Backgroundworker does things in the background (nonblocking)
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += DoItButDontInterruptMeDuh;
bw.RunWorkerAsync();
}
public event PropertyChangedEventHandler PropertyChanged;
public string SystemInformation { get => _systemInformation; set => _systemInformation = value; }
//Stub
public string getCPU()
{
return "Fancy CPU";
}
//Stub
public string getRAMsize()
{
return "1 PB";
}
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
//Stub
private string av()
{
return "Whatever av means.";
}
private void DoItButDontInterruptMeDuh(object sender, DoWorkEventArgs e)
{
// Simulate loading time
Thread.Sleep(5000);
SystemInformation = getCPU();
SystemInformation += "Memory: " + getRAMsize() + Environment.NewLine;
SystemInformation += "Free Space: " + GetTotalFreeSpace(sysdrive) + " GB" + Environment.NewLine;
if (is64BitSystem)
{
SystemInformation += getOS() + " 64bit" + Environment.NewLine;
}
else
{
SystemInformation += getOS() + " 32 Bit" + Environment.NewLine;
}
SystemInformation += "MAC Address : " + System.Text.RegularExpressions.Regex.Replace(GetMacAddress().ToString(), ".{2}", "$0 ") + Environment.NewLine;
SystemInformation += av();
OnPropertyChanged("SystemInformation");
}
//Stub
private object GetMacAddress()
{
return "Macintoshstreet 1234";
}
//Stub
private string getOS()
{
return "Cool OS";
}
//Stub
private string GetTotalFreeSpace(object sysdrive)
{
return "0";
}
}
and in the .xaml:
<TextBox Text={Binding Path=SystemInformation}/>
Your code doesn't show how to run the tasks in the background thread also you should point out that any attempt to manipulate UI element from background thread will result in an exception being thrown. As the UI elements are NOT thread safe. Also your xaml is not correct.
– XAMlMAX
Nov 22 at 14:26
Please, more noob friendly. Do I have to create a new class called SomeWindow (or SysInfo) ? what is InitWhatever(); supposed to be(same doesn't exist in current context)? NotifyOfPropertyChange(() => systemInformation); throws exception : doesn't exist in current context
– erma86
Nov 22 at 14:44
edited my answer accordingly
– Sebastian L
Nov 22 at 15:19
many thanks, but still got 1 exception : Type 'MainWindow' already defines a member called '.ctor' with the same parameter types
– erma86
Nov 22 at 15:46
probabily my bad since I pasted the code in a new class file and that's why it was throwin that exception. Moved the code in the MainWindow.cs file and the exception is gone...still textbox doesn't load the content.
– erma86
Nov 22 at 16:13
|
show 4 more comments
You are aquiring your data in the UI Thread.
You should load the data in the background thread and then, since you use wpf, binding the textbox text to a variable.
Example (This code is Copy'n'Paste ready):
// INotifyPropertyChanged is an Interface which enables binding of Properties in your window
public partial class MainWindow : Window, INotifyPropertyChanged
{
private string _systemInformation;
// Stub (works actually)
private bool is64BitSystem = (IntPtr.Size == 8);
// Stub
private string sysdrive = "YOLO\:";
public MainWindow()
{
InitializeComponent();
// Set Datacontext normally set to a viewmodel but ther is none in this code
this.DataContext = this;
// The Backgroundworker does things in the background (nonblocking)
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += DoItButDontInterruptMeDuh;
bw.RunWorkerAsync();
}
public event PropertyChangedEventHandler PropertyChanged;
public string SystemInformation { get => _systemInformation; set => _systemInformation = value; }
//Stub
public string getCPU()
{
return "Fancy CPU";
}
//Stub
public string getRAMsize()
{
return "1 PB";
}
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
//Stub
private string av()
{
return "Whatever av means.";
}
private void DoItButDontInterruptMeDuh(object sender, DoWorkEventArgs e)
{
// Simulate loading time
Thread.Sleep(5000);
SystemInformation = getCPU();
SystemInformation += "Memory: " + getRAMsize() + Environment.NewLine;
SystemInformation += "Free Space: " + GetTotalFreeSpace(sysdrive) + " GB" + Environment.NewLine;
if (is64BitSystem)
{
SystemInformation += getOS() + " 64bit" + Environment.NewLine;
}
else
{
SystemInformation += getOS() + " 32 Bit" + Environment.NewLine;
}
SystemInformation += "MAC Address : " + System.Text.RegularExpressions.Regex.Replace(GetMacAddress().ToString(), ".{2}", "$0 ") + Environment.NewLine;
SystemInformation += av();
OnPropertyChanged("SystemInformation");
}
//Stub
private object GetMacAddress()
{
return "Macintoshstreet 1234";
}
//Stub
private string getOS()
{
return "Cool OS";
}
//Stub
private string GetTotalFreeSpace(object sysdrive)
{
return "0";
}
}
and in the .xaml:
<TextBox Text={Binding Path=SystemInformation}/>
Your code doesn't show how to run the tasks in the background thread also you should point out that any attempt to manipulate UI element from background thread will result in an exception being thrown. As the UI elements are NOT thread safe. Also your xaml is not correct.
– XAMlMAX
Nov 22 at 14:26
Please, more noob friendly. Do I have to create a new class called SomeWindow (or SysInfo) ? what is InitWhatever(); supposed to be(same doesn't exist in current context)? NotifyOfPropertyChange(() => systemInformation); throws exception : doesn't exist in current context
– erma86
Nov 22 at 14:44
edited my answer accordingly
– Sebastian L
Nov 22 at 15:19
many thanks, but still got 1 exception : Type 'MainWindow' already defines a member called '.ctor' with the same parameter types
– erma86
Nov 22 at 15:46
probabily my bad since I pasted the code in a new class file and that's why it was throwin that exception. Moved the code in the MainWindow.cs file and the exception is gone...still textbox doesn't load the content.
– erma86
Nov 22 at 16:13
|
show 4 more comments
You are aquiring your data in the UI Thread.
You should load the data in the background thread and then, since you use wpf, binding the textbox text to a variable.
Example (This code is Copy'n'Paste ready):
// INotifyPropertyChanged is an Interface which enables binding of Properties in your window
public partial class MainWindow : Window, INotifyPropertyChanged
{
private string _systemInformation;
// Stub (works actually)
private bool is64BitSystem = (IntPtr.Size == 8);
// Stub
private string sysdrive = "YOLO\:";
public MainWindow()
{
InitializeComponent();
// Set Datacontext normally set to a viewmodel but ther is none in this code
this.DataContext = this;
// The Backgroundworker does things in the background (nonblocking)
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += DoItButDontInterruptMeDuh;
bw.RunWorkerAsync();
}
public event PropertyChangedEventHandler PropertyChanged;
public string SystemInformation { get => _systemInformation; set => _systemInformation = value; }
//Stub
public string getCPU()
{
return "Fancy CPU";
}
//Stub
public string getRAMsize()
{
return "1 PB";
}
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
//Stub
private string av()
{
return "Whatever av means.";
}
private void DoItButDontInterruptMeDuh(object sender, DoWorkEventArgs e)
{
// Simulate loading time
Thread.Sleep(5000);
SystemInformation = getCPU();
SystemInformation += "Memory: " + getRAMsize() + Environment.NewLine;
SystemInformation += "Free Space: " + GetTotalFreeSpace(sysdrive) + " GB" + Environment.NewLine;
if (is64BitSystem)
{
SystemInformation += getOS() + " 64bit" + Environment.NewLine;
}
else
{
SystemInformation += getOS() + " 32 Bit" + Environment.NewLine;
}
SystemInformation += "MAC Address : " + System.Text.RegularExpressions.Regex.Replace(GetMacAddress().ToString(), ".{2}", "$0 ") + Environment.NewLine;
SystemInformation += av();
OnPropertyChanged("SystemInformation");
}
//Stub
private object GetMacAddress()
{
return "Macintoshstreet 1234";
}
//Stub
private string getOS()
{
return "Cool OS";
}
//Stub
private string GetTotalFreeSpace(object sysdrive)
{
return "0";
}
}
and in the .xaml:
<TextBox Text={Binding Path=SystemInformation}/>
You are aquiring your data in the UI Thread.
You should load the data in the background thread and then, since you use wpf, binding the textbox text to a variable.
Example (This code is Copy'n'Paste ready):
// INotifyPropertyChanged is an Interface which enables binding of Properties in your window
public partial class MainWindow : Window, INotifyPropertyChanged
{
private string _systemInformation;
// Stub (works actually)
private bool is64BitSystem = (IntPtr.Size == 8);
// Stub
private string sysdrive = "YOLO\:";
public MainWindow()
{
InitializeComponent();
// Set Datacontext normally set to a viewmodel but ther is none in this code
this.DataContext = this;
// The Backgroundworker does things in the background (nonblocking)
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += DoItButDontInterruptMeDuh;
bw.RunWorkerAsync();
}
public event PropertyChangedEventHandler PropertyChanged;
public string SystemInformation { get => _systemInformation; set => _systemInformation = value; }
//Stub
public string getCPU()
{
return "Fancy CPU";
}
//Stub
public string getRAMsize()
{
return "1 PB";
}
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
//Stub
private string av()
{
return "Whatever av means.";
}
private void DoItButDontInterruptMeDuh(object sender, DoWorkEventArgs e)
{
// Simulate loading time
Thread.Sleep(5000);
SystemInformation = getCPU();
SystemInformation += "Memory: " + getRAMsize() + Environment.NewLine;
SystemInformation += "Free Space: " + GetTotalFreeSpace(sysdrive) + " GB" + Environment.NewLine;
if (is64BitSystem)
{
SystemInformation += getOS() + " 64bit" + Environment.NewLine;
}
else
{
SystemInformation += getOS() + " 32 Bit" + Environment.NewLine;
}
SystemInformation += "MAC Address : " + System.Text.RegularExpressions.Regex.Replace(GetMacAddress().ToString(), ".{2}", "$0 ") + Environment.NewLine;
SystemInformation += av();
OnPropertyChanged("SystemInformation");
}
//Stub
private object GetMacAddress()
{
return "Macintoshstreet 1234";
}
//Stub
private string getOS()
{
return "Cool OS";
}
//Stub
private string GetTotalFreeSpace(object sysdrive)
{
return "0";
}
}
and in the .xaml:
<TextBox Text={Binding Path=SystemInformation}/>
edited Nov 22 at 15:19
answered Nov 22 at 13:43
Sebastian L
706822
706822
Your code doesn't show how to run the tasks in the background thread also you should point out that any attempt to manipulate UI element from background thread will result in an exception being thrown. As the UI elements are NOT thread safe. Also your xaml is not correct.
– XAMlMAX
Nov 22 at 14:26
Please, more noob friendly. Do I have to create a new class called SomeWindow (or SysInfo) ? what is InitWhatever(); supposed to be(same doesn't exist in current context)? NotifyOfPropertyChange(() => systemInformation); throws exception : doesn't exist in current context
– erma86
Nov 22 at 14:44
edited my answer accordingly
– Sebastian L
Nov 22 at 15:19
many thanks, but still got 1 exception : Type 'MainWindow' already defines a member called '.ctor' with the same parameter types
– erma86
Nov 22 at 15:46
probabily my bad since I pasted the code in a new class file and that's why it was throwin that exception. Moved the code in the MainWindow.cs file and the exception is gone...still textbox doesn't load the content.
– erma86
Nov 22 at 16:13
|
show 4 more comments
Your code doesn't show how to run the tasks in the background thread also you should point out that any attempt to manipulate UI element from background thread will result in an exception being thrown. As the UI elements are NOT thread safe. Also your xaml is not correct.
– XAMlMAX
Nov 22 at 14:26
Please, more noob friendly. Do I have to create a new class called SomeWindow (or SysInfo) ? what is InitWhatever(); supposed to be(same doesn't exist in current context)? NotifyOfPropertyChange(() => systemInformation); throws exception : doesn't exist in current context
– erma86
Nov 22 at 14:44
edited my answer accordingly
– Sebastian L
Nov 22 at 15:19
many thanks, but still got 1 exception : Type 'MainWindow' already defines a member called '.ctor' with the same parameter types
– erma86
Nov 22 at 15:46
probabily my bad since I pasted the code in a new class file and that's why it was throwin that exception. Moved the code in the MainWindow.cs file and the exception is gone...still textbox doesn't load the content.
– erma86
Nov 22 at 16:13
Your code doesn't show how to run the tasks in the background thread also you should point out that any attempt to manipulate UI element from background thread will result in an exception being thrown. As the UI elements are NOT thread safe. Also your xaml is not correct.
– XAMlMAX
Nov 22 at 14:26
Your code doesn't show how to run the tasks in the background thread also you should point out that any attempt to manipulate UI element from background thread will result in an exception being thrown. As the UI elements are NOT thread safe. Also your xaml is not correct.
– XAMlMAX
Nov 22 at 14:26
Please, more noob friendly. Do I have to create a new class called SomeWindow (or SysInfo) ? what is InitWhatever(); supposed to be(same doesn't exist in current context)? NotifyOfPropertyChange(() => systemInformation); throws exception : doesn't exist in current context
– erma86
Nov 22 at 14:44
Please, more noob friendly. Do I have to create a new class called SomeWindow (or SysInfo) ? what is InitWhatever(); supposed to be(same doesn't exist in current context)? NotifyOfPropertyChange(() => systemInformation); throws exception : doesn't exist in current context
– erma86
Nov 22 at 14:44
edited my answer accordingly
– Sebastian L
Nov 22 at 15:19
edited my answer accordingly
– Sebastian L
Nov 22 at 15:19
many thanks, but still got 1 exception : Type 'MainWindow' already defines a member called '.ctor' with the same parameter types
– erma86
Nov 22 at 15:46
many thanks, but still got 1 exception : Type 'MainWindow' already defines a member called '.ctor' with the same parameter types
– erma86
Nov 22 at 15:46
probabily my bad since I pasted the code in a new class file and that's why it was throwin that exception. Moved the code in the MainWindow.cs file and the exception is gone...still textbox doesn't load the content.
– erma86
Nov 22 at 16:13
probabily my bad since I pasted the code in a new class file and that's why it was throwin that exception. Moved the code in the MainWindow.cs file and the exception is gone...still textbox doesn't load the content.
– erma86
Nov 22 at 16:13
|
show 4 more comments
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53432038%2fwpf-textbox-content-freezes-ui-on-load%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown