Let’s assume you create a DispatchTimer like this:
if (_updateTimer != null) return;
_updateTimer = new DispatcherTimer(DispatcherPriority.Normal) {Interval = new TimeSpan(0, 0, 0, Settings.Default.UpdateIntervallSec)};
_updateTimer.Tick += UpdateTimerOnTick;
_updateTimer.Start();
Now your system goes to sleep or suspend from working. After the systems resumes work, a NullPointerException is throw by the code. To avoid this I register on an event SystemEvents.PowerModeChanged += SystemEventsOnPowerModeChanged;
With the following code:
private void SystemEventsOnPowerModeChanged(object sender, PowerModeChangedEventArgs e)
{
if (e.Mode == PowerModes.Suspend)
{
if (_updateTimer == null) return;
_updateTimer.Tick -= UpdateTimerOnTick;
_updateTimer.IsEnabled = false;
_updateTimer.Stop();
}
if (e.Mode == PowerModes.Resume)
{
if (_updateTimer != null) return;
_updateTimer = new DispatcherTimer(DispatcherPriority.Normal) {Interval = new TimeSpan(0, 0, 0, Settings.Default.UpdateIntervallSec)};
_updateTimer.Tick += UpdateTimerOnTick;
_updateTimer.Start();
}
}
But this doesn’t solve the issue. The exception is called that the “UpdateTimerOnTick” method is null. Any good idea how to prevent this behavior?
You should set the variable _updateTimer to null when the system is suspended otherwise is your code on Resume not executed.
if (_updateTimer == null) return;
// your other code
_updateTimer = null;
Related
I have project that I click Button and it's will create a new PictureBox (pb) on a PictureBox1. And when I choose item on a combobox and PictureBox (pb) will appear in the position I want and the problem appears. How can I fix it or use "pb" in void comboBox3_SelectedIndexChanged. Thank you.
private void btaddagv_Click(object sender, EventArgs e)
{
AddNewPictureBox();
}
public System.Windows.Forms.PictureBox AddNewPictureBox()
{
System.Windows.Forms.PictureBox pb = new System.Windows.Forms.PictureBox();
pictureBox1.Controls.Add(pb);
pb.Name = "STT" + tbAdd.Text;
pb.Image = Image.FromFile("AGV-1.jpg");
pb.Height = 30;
pb.Width = 40;
pb.SizeMode = PictureBoxSizeMode.Zoom;
pb.Location = new System.Drawing.Point(tdx, 500);
tdx = tdx + 200;
return pb;
}
private void comboBox3_SelectedIndexChanged(object sender, EventArgs e)
{
if(comboBox3.SelectedItem == "A")
{
PictureBox pb = (PictureBox)sender;
pb.Location = lbA.Location;
}
}
And here is an error
If we make an assumption on this line:
pb.Name = "STT" + tbAdd.Text;
that tbAdd.Text contains the A, B, C, D etc that you're checking for here:
if(comboBox3.SelectedItem == "A")
Then your SelectedIndexChanged event handler should be:
private void comboBox3_SelectedIndexChanged(object sender, EventArgs e)
{
string selected = comboBox3.SelectedItem.ToString();
if (!string.IsNullOrWhitespace(selected))
{
PictureBox pb = picturebox1.Controls.OfType<PictureBox>().Where(p => p.Name == $"STT{selected}").FirstOrDefault();
if (pb != null)
{
Label lb = picturebox1.Controls.OfType<Label>().Where(l => l.Name == $"lb{selected}").FirstOrDefault();
if (lb != null)
pb.Location = lb.Location;
}
}
}
I've made some extra assumptions here. First I've assumed that the "lbA" control you're referring to is a Label. The second assumption is that lbA and the other controls are all share the same parent (picturebox1)
What the above is doing is getting the value of the SelectedItem (if we use your example with the letter A) then attempts to find any PictureBox controls that have the name STTA. If it finds one it looks for a Label on the same parent called lbA. If that exists then it moves the picturebox control to the location of the label.
I have very little experience using threads so I might be missing some pretty basic infomration in my logic.
Anyway, I'm trying to update a GMapMarker based on 1000ms timer.
My Timer start:
aTimer = new System.Timers.Timer();
aTimer.Elapsed += OnTimerEvent;
aTimer.Interval = 1000;
aTimer.Enabled = true;
My update code:
int _positionIncriment = 0;
private void OnTimerEvent(object sender, System.Timers.ElapsedEventArgs e)
{
PointLatLng p = m_debugPath[_positionIncriment];
_gpsMarker.Position = p;
_positionIncriment++;
_gmap.ForceUpdateOverlays();
if(_positionIncriment >= m_debugPath.Count)
{
_positionIncriment = 0;
}
}
As I step through this block, it stops at the ForceUpdateOverlays and never progresses further.
As far as I can tell the render functions of GMap is within its own thread which might be causing issue.. but as I said, only have a basic understanding of threading I'm a bit lost.
Any help would be great.
Use a DispatcherTimer instead of Timer. Its Tick event is fired in the UI thread:
using System.Windows.Threading;
...
aTimer = new DispatcherTimer();
aTimer.Tick += OnTimerEvent;
aTimer.Interval = TimeSpan.FromSeconds(1);
aTimer.IsEnabled = true; // or aTimer.Start();
...
private void OnTimerEvent(object sender, EventArgs e)
{
...
}
Looks like I needed to invoke the Dispatcher before running my code.
I don't know is this the the 'correct' way to solve this problem, but the end result is what i was desiring.
Hope this helps someone else.
int _positionIncrement = 0;
private void OnTimerEvent(object sender, System.Timers.ElapsedEventArgs e)
{
this.Dispatcher.Invoke(() =>
{
PointLatLng p = m_debugPath[_positionIncrement];
_gps.Position = p;
_positionIncrement++;
_gmap.ForceUpdateOverlays();
if(_positionIncrement >= m_debugPath.Count)
{
_positionIncrement = 0;
}
});
}
I want to load mono assemblies from memory. So instead of using the usual mono_domain_assembly_open I use mono_image_open_from_data. The returned image and assembly are OK and the status is MONO_IMAGE_OK.
m_valid = true;
mono_set_dirs(assembliesDir.c_str(), configDir.c_str());
MonoImageOpenStatus status = MONO_IMAGE_ERROR_ERRNO;
m_image = mono_image_open_from_data(data, size, 1, &status);
if(status != MONO_IMAGE_OK || m_image == NULL) {
m_valid = false;
return;
}
m_assembly = mono_assembly_load_from( m_image, assembliesName.c_str(), &status);
if(status != MONO_IMAGE_OK || m_assembly == NULL) {
m_valid = false;
return;
}
However when I try to get a class from the assembly using :
MonoClass *my_class = mono_class_from_name (m_image, name_space.c_str(), name.c_str());
I get my_class == NULL. When I use the usual mono_image_open_from_data Mono returns a valid class instance.
I suspect that the method doesn't load correctly all the references. Do you have any suggestions or workarounds ?
I was trying to add new row to my database table and it seams that everything is going well in the application WPF and when i close the application the database has not changed(new record was not added in the database ) I tried to use dataadapters so here is my class that i use and the code behing
DD.cs
namespace WpfApplication2
{
class DD
{
private Database1DataSetTableAdapters.Table1TableAdapter _cpuAdapter = null;
protected Database1DataSetTableAdapters.Table1TableAdapter Adapter
{
get
{
if (_cpuAdapter == null)
_cpuAdapter = new Database1DataSetTableAdapters.Table1TableAdapter();
return _cpuAdapter;
}
}
[System.ComponentModel.DataObjectMethodAttribute
(System.ComponentModel.DataObjectMethodType.Insert, true)]
public bool AddCPU(string Naslov, string Avtor, string Lokacija, int Broj, string
Zabeleska, string Izdava)
{
Database1DataSet.Table1DataTable cpus = new Database1DataSet.Table1DataTable();
Database1DataSet.Table1Row cpu = cpus.NewTable1Row();
cpu.Naslov = Naslov;
if (Naslov == null) cpu.SetNaslovNull();
else cpu.Naslov = Naslov;
if (Avtor == null) cpu.SetAvtorNull();
else cpu.Avtor = Avtor;
if (Zabeleska == null) cpu.SetZabeleskaNull();
else cpu.Zabeleska = Zabeleska;
if (Izdava == null) cpu.SetIzdavaNull();
else cpu.Izdava = Izdava;
if (Broj == null) cpu.SetBrojNull();
else cpu.Broj = Broj;
if (Lokacija == null) cpu.SetLokacijaNull();
else cpu.Lokacija = Lokacija;
cpus.AddTable1Row(cpu);
int rowsAffected = Adapter.Update(cpus);
// Return true if precisely one row was inserted, otherwise false
return rowsAffected == 1;
}
HERE IS THE CODE BEHIND
it's an event on button click
string n, a, z,t,l;
int b;
l = txtLokacija.Text;
t = txtBroj.Text;
b = Convert.ToInt32(t);
n = txtNaslov.Text;
a = txtAvtor.Text;
z = txtZabeleska.Text;
t = "NONE";
txtZabeleska.Clear();
DD obj1=new DD();
obj1.AddCPU(n,a,l,b,z,t);
I found IT....when i finished the application and published then it seemed everything ok the database was working properly..i;ve restarted the PC and the newly added record
Is there a way to get all BindingExpression objects for a Window?
I am trying to refresh the form when the number PropertyChanged events that need to be fired to refresh a form is too high and not a good option. I am thinking doing it the other way that the form/window can re-query all bindings.
If you raise PropertyChanged with the PropertyChangedEventArgs that have a parameter of null or String.Empty the bindings of all properties will update.
[MSDN Reference]
Doing it the other way around is a lot more complicated and probably more performance consuming i think. You would need to check every DependencyProperty of every DependencyObject in the whole window for bindings.
Edit: Wrote the following sketchy extension method which does what you asked for, it's awfully inefficient (there is probably room for improvement but you're still dealing with an algorithm of considerable complexity):
public static void UpdateAllBindings(this DependencyObject o)
{
//Immediate Properties
List<FieldInfo> propertiesAll = new List<FieldInfo>();
Type currentLevel = o.GetType();
while (currentLevel != typeof(object))
{
propertiesAll.AddRange(currentLevel.GetFields());
currentLevel = currentLevel.BaseType;
}
var propertiesDp = propertiesAll.Where(x => x.FieldType == typeof(DependencyProperty));
foreach (var property in propertiesDp)
{
BindingExpression ex = BindingOperations.GetBindingExpression(o, property.GetValue(o) as DependencyProperty);
if (ex != null)
{
ex.UpdateTarget();
}
}
//Children
int childrenCount = VisualTreeHelper.GetChildrenCount(o);
for (int i = 0; i < childrenCount; i++)
{
var child = VisualTreeHelper.GetChild(o, i);
child.UpdateAllBindings();
}
}
Just for reference, WPF itself does exactly this (iterates through all the data bound properties) when you call BindingOperations.ClearAllBindings().
The code for that is the following:
public static void ClearAllBindings(DependencyObject target)
{
if (target == null)
{
throw new ArgumentNullException("target");
}
LocalValueEnumerator localValueEnumerator = target.GetLocalValueEnumerator();
ArrayList arrayList = new ArrayList(8);
while (localValueEnumerator.MoveNext())
{
LocalValueEntry current = localValueEnumerator.Current;
if (BindingOperations.IsDataBound(target, current.Property))
{
arrayList.Add(current.Property);
}
}
for (int i = 0; i < arrayList.Count; i++)
{
target.ClearValue((DependencyProperty)arrayList[i]);
}
}
LocalValueEnumerator is public so you can use it too.
You should be able to deduce the solution from this easily.