I'm new in WPF trying to use ReactiveUI,
I want to call 3 different method based on property value changed.
so
public int Number
{
set
{
number = val;
if (_number == 1) Call1()
else if (_number == 2) call2()
else if (_number == 3) call3()
}
}
above is working but now I'm trying using ReactiveUI
so what i did
this.ObservableForProperty(x => x._number).Subscribe( => Call1());
is there any way to achieve above?
If you set up your property like this (assuming your class derives from ReactiveObject):
public int Number
{
get
{
return _number;
}
set
{
this.RaiseAndSetIfChanged(ref _number, value);
}
}
Or, you need to get it to fire property changed notifications some other way.
You didn't say if you are observing the property within the class itself or from a different one. For example, is this all occurring in your ViewModel or in your View watching your ViewModel?
If within the ViewModel with the Number property, I would try something along these lines:
this.WhenAnyValue(t => t.Number)
.Subscribe(i =>
{
if (i == 1)
{
Call1();
}
else if (i == 2)
{
Call2();
}
else if (i == 3)
{
Call3();
}
}
);
If you were in your View that had a ViewModel property holding the ViewModel with the Number property I would try:
this.ObservableForProperty(t => t.ViewModel.Number,i => i)
.Subscribe(i =>
{
if (i == 1)
{
Call1();
}
else if (i == 2)
{
Call2();
}
else if (i == 3)
{
Call3();
}
}
);
How about this:
this.WhenAnyValue(x => x.Number)
.Where(x => x == 1)
.Subscribe(Call1);
Related
The Listview(partial page) is not getting refreshed when I click the button. It keeps on adding the rows whenever the buttons are clicked.
Below are the functions for adding the drivers.
function getDriversFromPolicy_CA7() : CA7CommAutoDriver[] {
var drivers = this.Policy.LatestPeriod.CA7Line.Drivers // **this** Contingency Entity
var excludeDrivers = this.ExcludeDrivers_CA7.toList() // Contingency entity has a ExcludeDrivers_CA7 array
if(excludeDrivers.Empty) {
drivers?.each(\driver -> this.addToExcludeDrivers_CA7(driver) )
} else {
drivers.each(\driver -> {
if (excludeDrivers.where(\elt -> elt.LicenseNumber == driver.LicenseNumber).toList().Count == 0) {
this.addToExcludeDrivers_CA7(driver)
}
})
}
return this.ExcludeDrivers_CA7
}
function getDriversFromTransaction_CA7() : CA7CommAutoDriver[] {
var drivers = this.PolicyPeriod.CA7Line.Drivers.toList()
var excludeDrivers = this.ExcludeDrivers_CA7.toList()
if(this.ExcludeDrivers_CA7.IsEmpty) {
drivers?.each(\driver -> this.addToExcludeDrivers_CA7(driver) )
} else {
// this.ExcludeDrivers_CA7.toList().retainAll(drivers.toList())
drivers.each(\driver -> {
if (excludeDrivers.where(\elt -> elt.LicenseNumber == driver.LicenseNumber).toList().Count == 0) {
this.addToExcludeDrivers_CA7(driver)
}
})
}
return this.ExcludeDrivers_CA7
}
function removeDrivers_CA7(driver : CA7CommAutoDriver) {
this.removeFromExcludeDrivers_CA7(driver)
}
pcf screenshot for reference
UI screenshot for reference
Coding in Xamarin IOS. I have a drop down list type popup, where, if The end user types in a new value, I want to ask a yes/no question: Do You want to add a new row?
The control is inside a UIStackView, which is inside a container UIView, which is in turn inside another which is presented via segue. Xamarin demanded a UIPopoverController, which I implemented. Here is The code I have so far:
using System.Threading.Tasks;
using Foundation;
using UIKit;
namespace PTPED_Engine
{
public enum MessagePopupType
{
YesNo = 1,
OKCancel = 2,
OKOnly = 3
}
public enum PopupResultType
{
OK = 1,
Cancel = 2,
Yes = 3,
No = 4
}
public static class AlertPopups
{
static NSObject nsObject;
public static void Initialize(NSObject nsObject)
{
AlertPopups.nsObject = nsObject;
}
public static Task<PopupResultType> AskUser(UIViewController parent, UIView V, string strTitle, string strMsg, MessagePopupType mpt)
{
using (UIPopoverController pc = new UIPopoverController(parent))
{
// pc.ContentViewController
// method to show an OK/Cancel dialog box and return true for OK, or false for cancel
var taskCompletionSource = new TaskCompletionSource<PopupResultType>();
var alert = UIAlertController.Create(strTitle, strMsg, UIAlertControllerStyle.ActionSheet);
// set up button event handlers
if (mpt == MessagePopupType.OKCancel)
{
alert.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Default, a => taskCompletionSource.SetResult(PopupResultType.OK)));
alert.AddAction(UIAlertAction.Create("Cancel", UIAlertActionStyle.Default, a => taskCompletionSource.SetResult(PopupResultType.Cancel)));
}
if (mpt == MessagePopupType.YesNo)
{
alert.AddAction(UIAlertAction.Create("Yes", UIAlertActionStyle.Default, a => taskCompletionSource.SetResult(PopupResultType.Yes)));
alert.AddAction(UIAlertAction.Create("No", UIAlertActionStyle.Default, a => taskCompletionSource.SetResult(PopupResultType.No)));
}
if (mpt == MessagePopupType.OKOnly)
{
alert.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Default, a => taskCompletionSource.SetResult(PopupResultType.OK)));
}
// show it
nsObject.InvokeOnMainThread(() =>
{
pc.PresentFromRect(V.Bounds, V, UIPopoverArrowDirection.Any, true);
});
return taskCompletionSource.Task;
}
}
}
}
and I invoke it as follows:
LookupCombo.Completed += async (object sender, CompletedEventArgs e) =>
{
C1AutoComplete AC = (C1AutoComplete)sender;
if (AC.Text.Trim() != "")
{
string sColName = AC.AccessibilityIdentifier.Trim();
var ValuesVC = (List<Lookupcombo_Entry>)AC.ItemsSource;
var IsThisAHit = from Lookupcombo_Entry in ValuesVC
where Lookupcombo_Entry.sDispVal.ToUpper().Trim() == e.value.ToUpper().Trim()
select Lookupcombo_Entry.sMapVal;
if (!IsThisAHit.Any())
{
string sTitle = "";
string sFull = _RM.GetString(sColName);
if (sFull == null) { sFull = "???-" + sColName.Trim(); }
sTitle = " Add New " + sFull.Trim() + "?";
string sPPrompt = "Do you want to add a new " + sFull.Trim() + " named " + AC.Text.Trim() + " to the Database?";
var popupResult = await AlertPopups.AskUser(CurrentViewController(), V, sTitle, sPPrompt, MessagePopupType.YesNo);
}
}
};
CurrentViewController is defined like this:
private UIViewController CurrentViewController()
{
var window = UIApplication.SharedApplication.KeyWindow;
var vc = window.RootViewController;
while (vc.PresentedViewController != null)
{
vc = vc.PresentedViewController;
}
return vc;
}
This does nothing. It hangs The user interface.
This should be built in, but it is only built in in Xamarin.Forms, which I do not want to use.
I have no problem in doing this stuff with an await, but this is simply not working. Can anyone help?
Thanks!
You can just use the ACR UserDialogs library:
https://github.com/aritchie/userdialogs
This is a solution I provided a few years ago, I think it is an ugly hack, compared to your elegant approach. You did not say what part does not work exactly, that might help spot the problem.
Here is my solution from a few years back:
iphone UIAlertView Modal
I have the following code which copies property values from one object to another objects by matching their property names:
public static void CopyProperties(object source, object target,bool caseSenstive=true)
{
PropertyInfo[] targetProperties = target.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
PropertyInfo[] sourceProperties = source.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (PropertyInfo tp in targetProperties)
{
var sourceProperty = sourceProperties.FirstOrDefault(p => p.Name == tp.Name);
if (sourceProperty == null && !caseSenstive)
{
sourceProperty = sourceProperties.FirstOrDefault(p => p.Name.ToUpper() == tp.Name.ToUpper());
}
// If source doesn't have this property, go for next one.
if(sourceProperty ==null)
{
continue;
}
// If target property is not writable then we can not set it;
// If source property is not readable then cannot check it's value
if (!tp.CanWrite || !sourceProperty.CanRead)
{
continue;
}
MethodInfo mget = sourceProperty.GetGetMethod(false);
MethodInfo mset = tp.GetSetMethod(false);
// Get and set methods have to be public
if (mget == null)
{
continue;
}
if (mset == null)
{
continue;
}
var sourcevalue = sourceProperty.GetValue(source, null);
tp.SetValue(target, sourcevalue, null);
}
}
This is working well when the type of properties on target and source are the same. But when there is a need for casting, the code doesn't work.
For example, I have the following object:
class MyDateTime
{
public static implicit operator DateTime?(MyDateTime myDateTime)
{
return myDateTime.DateTime;
}
public static implicit operator DateTime(MyDateTime myDateTime)
{
if (myDateTime.DateTime.HasValue)
{
return myDateTime.DateTime.Value;
}
else
{
return System.DateTime.MinValue;
}
}
public static implicit operator MyDateTime(DateTime? dateTime)
{
return FromDateTime(dateTime);
}
public static implicit operator MyDateTime(DateTime dateTime)
{
return FromDateTime(dateTime);
}
}
If I do the following, the implicit cast is called and everything works well:
MyDateTime x= DateTime.Now;
But when I have a two objects that one of them has a DateTime and the other has MyDateTime, and I am using the above code to copy properties from one object to other, it doesn't and generate an error saying that DateTime can not converted to MyTimeDate.
How can I fix this problem?
One ghastly approach which should work is to mix dynamic and reflection:
private static T ConvertValue<T>(dynamic value)
{
return value; // This will perform conversion automatically
}
Then:
var sourceValue = sourceProperty.GetValue(source, null);
if (sourceProperty.PropertyType != tp.PropertyType)
{
var method = typeof(PropertyCopier).GetMethod("ConvertValue",
BindingFlags.Static | BindingFlags.NonPublic);
method = method.MakeGenericMethod(new[] { tp.PropertyType };
sourceValue = method.Invoke(null, new[] { sourceValue });
}
tp.SetValue(target, sourceValue, null);
We need to use reflection to invoke the generic method with the right type argument, but dynamic typing will use the right conversion operator for you.
Oh, and one final request: please don't include my name anywhere near this code, whether it's in comments, commit logs. Aargh.
I'm struggling with the SharePoint 2007 AfterProperties. I've a people input field, where several people can be added.
On the ItemUpdating event I now need to determine which users were added, removed or stayed the same.
Unfortunately this becomes quit difficult, as the id of the untouched users turns to -1 in the AfterProperties, so that I cant not use SPFieldUserValueCollection to find the user.
An example. properties.ListItem["AssignedTo"].ToString() shows:
1;#domain\user1;#2;#domain\user2
properties.AfterProperties["AssignedTo"].ToString() shows:
-1;#domain\user1;#-1;#domain\user2;#3;#domain\user3 <-Added a user
I planned to use following code, to determine removed and added users:
foreach (SPFieldUserValue oldUser in oldUserCollection)
{
if (newUserCollection.Find(x => x.LookupId == oldUser.LookupId) == null)
{
RemoveRole(aListItem, oldUser.User, roleDefCollection[workerRoleName]);
}
}
foreach (SPFieldUserValue newUser in newUserCollection)
{
if(oldUserCollection.Find(x => x.User.LoginName == newUser.LookupValue) == null)
{
AddRole(aListItem, newUser.User, roleDefCollection[workerRoleName]);
}
}
How can I archive, that the AfterProperties show the right lookupid?
Solved the problem by myself. Instead of using the SPFieldUserCollection I'm now using a list and try to parse all the information by myself out of the string.
Regex reg = new Regex(#"\;\#");
string[] usernameParts = reg.Split(usernames);
List<SPUser> list = new List<SPUser>();
int id;
foreach (string s in usernameParts)
{
if (!string.IsNullOrEmpty(s))
{
if (!Int32.TryParse(s, out id))
{
if (list.Find(x => x.ID == spweb.Users[s].ID) == null)
list.Add(spweb.Users[s]);
}
else
{
if (Convert.ToInt32(s) != -1)
{
if (list.Find(x => x.ID == Convert.ToInt32(s)) == null)
list.Add(spweb.Users.GetByID(Convert.ToInt32(s)));
}
}
}
}
i'm having some issues getting the .Filter() method to work in subsonic, and i'm constantly getting errors like the one below:
Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.
Line 36: bool remove = false;
Line 37: System.Reflection.PropertyInfo pi = o.GetType().GetProperty(w.ColumnName);
Line 38: if (pi.CanRead)
Line 39: {
Line 40: object val = pi.GetValue(o, null);
i'm making calls like the one below- is this the corrent way to use it? There seems to be no documentation on the use of this method
NavCollection objTopLevelCol = objNavigation.Where(Nav.Columns.NavHigherID,Comparison.Equals, 0).Filter();
thanks in advance
The value you filter against needs to be the Property Name, not the database column name.
You might try this:
lCol = objNavigation.Where(Nav.HigherIDColumn.PropertyName,Comparison.Equals, 0).Filter();
Or here's a slightly more verbose method that works for me based on custom overrides of the .Filter() method. It seemed to work better (for me at least) by explicitly creating the Where beforehand:
SubSonic.Where w = new SubSonic.Where();
w.ColumnName = Nav.HigherIDColumn.PropertyName;
w.Comparison = SubSonic.Comparison.NotIn;
w.ParameterValue = new string[] { "validvalue1", "validvalue2" };
lCol = objNavigation.Filter(w, false);
Here's the overrides:
/// <summary>
/// Filters an existing collection based on the set criteria. This is an in-memory filter.
/// All existing wheres are retained.
/// </summary>
/// <returns>NavCollection</returns>
public NavCollection Filter(SubSonic.Where w)
{
return Filter(w, false);
}
/// <summary>
/// Filters an existing collection based on the set criteria. This is an in-memory filter.
/// Existing wheres can be cleared if not needed.
/// </summary>
/// <returns>NavCollection</returns>
public NavCollection Filter(SubSonic.Where w, bool clearWheres)
{
if (clearWheres)
{
this.wheres.Clear();
}
this.wheres.Add(w);
return Filter();
}
/// <summary>
/// Filters an existing collection based on the set criteria. This is an in-memory filter.
/// Thanks to developingchris for this!
/// </summary>
/// <returns>NavCollection</returns>
public NavCollection Filter()
{
for (int i = this.Count - 1; i > -1; i--)
{
Nav o = this[i];
foreach (SubSonic.Where w in this.wheres)
{
bool remove = false;
System.Reflection.PropertyInfo pi = o.GetType().GetProperty(w.ColumnName);
if (pi != null && pi.CanRead)
{
object val = pi.GetValue(o, null);
if (w.ParameterValue is Array)
{
Array paramValues = (Array)w.ParameterValue;
foreach (object arrayVal in paramValues)
{
remove = !Utility.IsMatch(w.Comparison, val, arrayVal);
if (remove)
break;
}
}
else
{
remove = !Utility.IsMatch(w.Comparison, val, w.ParameterValue);
}
}
if (remove)
{
this.Remove(o);
break;
}
}
}
return this;
}
And SubSonic 2.0 doesn't actually support In/NotIn for the IsMatch function, so here's the customized version that does (in SubSonic\Utility.cs):
public static bool IsMatch(SubSonic.Comparison compare, object objA, object objB)
{
if (objA.GetType() != objB.GetType())
return false;
bool isIntegerVal = (typeof(int) == objA.GetType());
bool isDateTimeVal = (typeof(DateTime) == objA.GetType());
switch (compare)
{
case SubSonic.Comparison.In:
case SubSonic.Comparison.Equals:
if (objA.GetType() == typeof(string))
return IsMatch((string)objA, (string)objB);
else
return objA.Equals(objB);
case SubSonic.Comparison.NotIn:
case SubSonic.Comparison.NotEquals:
return !objA.Equals(objB);
case SubSonic.Comparison.Like:
return objA.ToString().Contains(objB.ToString());
case SubSonic.Comparison.NotLike:
return !objA.ToString().Contains(objB.ToString());
case SubSonic.Comparison.GreaterThan:
if (isIntegerVal)
{
return ((int)objA > (int)objB);
}
else if (isDateTimeVal)
{
return ((DateTime)objA > (DateTime)objB);
}
break;
case SubSonic.Comparison.GreaterOrEquals:
if (isIntegerVal)
{
return ((int)objA >= (int)objB);
}
else if (isDateTimeVal)
{
return ((DateTime)objA >= (DateTime)objB);
}
break;
case SubSonic.Comparison.LessThan:
if (isIntegerVal)
{
return ((int)objA < (int)objB);
}
else if (isDateTimeVal)
{
return ((DateTime)objA < (DateTime)objB);
}
break;
case SubSonic.Comparison.LessOrEquals:
if (isIntegerVal)
{
return ((int)objA <= (int)objB);
}
else if (isDateTimeVal)
{
return ((DateTime)objA <= (DateTime)objB);
}
break;
}
return false;
}
IF you're using .net 3.5 you could just do this with a lambda function:
NavCollection objTopLevelCol =
objNavigation.Where(nav => nav.NavHigherID == 0);
Filter is designed to work on a collection - is "objNavigation" a collection? The problem you're running into is that the criteria for Filter() can't be met with the column name "NavHigherID".
I was having same prob, try doing your filter like this :
lCol = objNavigation.Where("NavHigherID",Comparison.Equals, 0).Filter();