casting object using name - c#

I need to cast different objects to different types using the literal string name. Some example code:
string controlName = "Control";
string stringName = "string";
string panelName = "Panel";
var x = Panel();
((Control)x).Name = "SomeName";
The above code works of course, but instead of this line
((Control)x).Name = "Normal";
How do I use the line
((controlName)x).Name = "Awesome";
I hope this makes sense, but if I need to explain further I can try.
I am creating a series of questions defined in an xml schema. The Question will vary such as
1. What time did this happen.
2 Why did this happen.
3. What type was this(type 1,type 2, type3)
All of these are read by one base control. 1 needs the answer control to be a date time picker, two needs a textbox, 3 needs a combobox.
I would subscribe to the textchange event of the textbox, the value changed event of the datetimepicker, and the selectedindexchange event of the combobox.
This is oversimplifying it, what I am actually doing is with controls and created events.
The way I am handling it now, is a gigantic case statement. I wondered if there was an easier way to do with with conversion of the control to the type defined in the xml document(string value)
EDIT*
Code as was asked for
namespace ScriptControl
{
public partial class ScriptItem
{
public FollowupEvent ActiveEvent{get;set;}
public event EventHandler AnswerChanged;
#region Constructors
public ScriptItem()
{
}
public ScriptItem(DataRow row)
{
}
public ScriptItem(XElement xelem,FollowupEvent activeEvent,int instanceID)
{
ActiveEvent = activeEvent;
InstanceID = instanceID;
try
{
Question = xelem.Elements("Text").First().Value.ToString();
AnswerType = xelem.Elements("Type").First().Value.ToString();
ControlType = xelem.Elements("Control").First().Attribute("Type").Value.ToString();
ActivityID = Convert.ToInt32(xelem.Attribute("ID").Value.ToString());
ScriptItemType = xelem.Elements("ScriptItemType").First().Value.ToString();
ScriptItemQuestionType = xelem.Elements("QuestionType").First().Value.ToString();
InputControl = ConfigureInputControl(xelem.Elements("Control").First().Attribute("Type").Value.ToString());
QuestionControl = ConfigureQuestionControl(xelem.Elements("Control").First().Attribute("Type").Value.ToString());
Prompt = xelem.Elements("Prompt").First().Value.ToString();
}
catch { }
}
#endregion
#region Public Properties
public string Prompt { get; set; }
public Panel QuestionPanel = new Panel();
public int ActivityID { get; set; }
public string Question { get; set; }
public string AnswerType { get; set; }
public object Result { get; set; }
public Control InputControl { get; set; }
public string ControlType { get; set; }
public Control QuestionControl { get; set; }
public string ScriptItemType { get; set; }
public string ScriptItemQuestionType { get; set; }
public int InstanceID { get; set; }
public ScriptControl.Entities.ScriptControlBase ScriptBaseControl { get; set; }
#endregion
public Control ConfigureInputControl(string controlType)
{
switch (controlType)
{
case "Checkbox":
InputControl = new CheckBox();
break;
case "BooleanQuestion":
InputControl = new BooleanQuestion();
((BooleanQuestion)InputControl).AnswerChanged += ScriptItem_AnswerChanged;
((BooleanQuestion)InputControl).SetQuestion(Question);
break;
case "TextBox":
InputControl = new TextBox();
((TextBox)InputControl).KeyDown += ScriptItem_AnswerChanged;
break;
case "RadioButton":
InputControl = new RadioButton();
break;
case "DropDown":
InputControl = new RadioButton();
break;
case "DateTimePicker":
InputControl = new DateTimePicker();
((DateTimePicker)InputControl).KeyDown += ScriptItem_AnswerChanged;
break;
case ".CustomControls.SmartParts.CauseForRepair":
case".CustomControls.SmartParts.Airlines":
case ".CustomControls.SmartParts.DREntry":
InputControl = GetUIControl();
((FN_ControlBase)InputControl).PropertyChanged += ScriptItem_AnswerChanged;
break;
}
return InputControl;
}
private void ScriptItem_AnswerChanged(object sender, EventArgs e)
{
Dictionary<string, object> workFlowParams = new Dictionary<string, object>();
switch (ControlType)
{
case "BooleanQuestion":
Control x = ((Control)sender).Parent.Parent.Parent;
Result = ((BooleanQuestion)x).Answer;
workFlowParams.Add("QuestionID",Activity);
workFlowParams.Add("InstanceID", InstanceID);
workFlowParams.Add("Result",Result);
break;
case "TextBox":
if (((KeyEventArgs)e).KeyValue == 13)
{
Result = ((TextBox)sender).Text;
workFlowParams.Add("QuestionID", Activity);
workFlowParams.Add("InstanceID", InstanceID);
workFlowParams.Add("Result", Result);
}
break;
case "DateTimePicker":
if (((KeyEventArgs)e).KeyValue == 13)
{
Result = ((DateTimePicker)sender).Text;
workFlowParams.Add("QuestionID", Activity);
workFlowParams.Add("InstanceID", InstanceID);
workFlowParams.Add("Result", Result);
}
break;
case ".CustomControls.SmartParts.Airlines":
case ".CustomControls.SmartParts.CauseForRepairUI":
case ".CustomControls.SmartParts.CancelCallUI":
case ".CustomControls.SmartParts.CostCenter":
case ".CustomControls.SmartParts.ReadyToBill":
case ".CustomControls.SmartParts.TemporaryFix":
case ".CustomControls.SmartParts.BrakeRepairFollowup":
case ".CustomControls.SmartParts.DREntry":
default:
if (((PropertyChangedEventArgs)e).PropertyName == "WorkComplete" & Convert.ToBoolean(((.CustomControls.FN_ControlBase)sender).GetPropertyValue("WorkComplete")) == true)
{
foreach (var propty in ((.CustomControls.FN_ControlBase)sender).GetType().GetProperties())
{
if (ActiveEvent.HasProperty(propty.Name) & propty.Name != "EventID")
{
ActiveEvent.SetPropertyValue(propty.Name, ((Control)sender).GetPropertyValue(propty.Name));
}
}
}
workFlowParams.Add("QuestionID", Activity);
workFlowParams.Add("InstanceID", InstanceID);
workFlowParams.Add("Result", ActiveEvent);
break;
}
AnswerChanged(workFlowParams, e);
}
public Control ConfigureQuestionControl(string controlType)
{
switch (controlType)
{
case "BooleanQuestion":
((BooleanQuestion)InputControl).SetQuestion(Question);
break;
case "TextBox":
QuestionControl = new Label { Visible = true, Location = new Point(0, 0), Text = Question};
break;
case "DateTimePicker":
QuestionControl = new Label { Visible = true, Location = new Point(0, 0), Text = Question};
break;
}
return QuestionControl;
}
public Control ConfigureControl()
{
var height = 0;
var width = 0;
ScriptBaseControl = new ScriptControl.Entities.ScriptControlBase();
if (InputControl is BooleanQuestion || ScriptItemType == "Control")
{
InputControl = ConfigureInputControl(ControlType);
ScriptBaseControl.AddControl(InputControl);
ScriptBaseControl.SetPrompt(Prompt);
foreach (Control c in ScriptBaseControl.FilterControls(ctl => !(ctl is Panel) && !(ctl is FlowLayoutPanel) && !(ctl is GroupBox) && !(ctl is ScriptControlBase)))
{
height = height + c.Height;
if (c.Width > width)
{
width = c.Width;
}
}
ScriptBaseControl.Size = new Size(width, height);
}
else
{
FlowLayoutPanel x = new FlowLayoutPanel();
x.Controls.Add(QuestionControl);
x.Controls.Add(InputControl);
foreach (Control c in ScriptBaseControl.FilterControls(ctl => !(ctl is Panel) && !(ctl is FlowLayoutPanel) && !(ctl is GroupBox) && !(ctl is ScriptControlBase)))
{
height = height + c.Height;
if (c.Width > width)
{
width = c.Width;
}
}
x.Size = new Size(width, height);
ScriptBaseControl.Size = x.Size;
ScriptBaseControl.AddControl(x);
ScriptBaseControl.SetPrompt(Prompt);
}
return ScriptBaseControl;
}
private Control GetUIControl()
{
Control uiControl = new Control();
switch (ControlType)
{
case ".CustomControls.SmartParts.Air":
uiControl = new .CustomControls.SmartParts.Airlines(ActiveEvent.EventID) { ExternalSave = true};
break;
case ".CustomControls.SmartParts.CauseFor":
uiControl = new .CustomControls.SmartParts.CauseForRepairUI() { ExternalSave = true };
break;
case ".CustomControls.SmartParts.Cancel":
uiControl = new .CustomControls.SmartParts.CancelCallUI() { ExternalSave = true,EventID = ActiveEvent.EventID };
break;
case ".CustomControls.SmartParts.Cost":
uiControl = new .CustomControls.SmartParts.CostCenter() { ExternalSave = true};
break;
case ".CustomControls.SmartParts.ReadyTo":
uiControl = new .CustomControls.SmartParts.ReadyToBill(ActiveEvent.EventID) { ExternalSave = true, EventID = ActiveEvent.EventID };
break;
case ".CustomControls.SmartParts.Temporary":
uiControl = new .CustomControls.SmartParts.TemporaryFix() { ExternalSave = true};
break;
case ".CustomControls.SmartParts.RepairFollowup":
uiControl = new .CustomControls.SmartParts.BrakeRepairFollowup() { ExternalSave = true, EventID = ActiveEvent.EventID};
break;
case ".CustomControls.SmartParts.Entry":
uiControl = new .CustomControls.SmartParts.DREntry() { ExternalSave = true };
break;
}
return uiControl;
}
}
}

You can't do this because C# is a statically typed language. The type you want to cast should be known at compile time so the compiler can tread x as Control (or whatever) in the rest of the code.If you could do this:
((controlName)x).Name = "Awesome";
There is no way to know what is the value of controlName or is it a valid type name until runtime.So the type of x can not be determined at compile time which violates the type-safety.
The only exception to static typing in C# is dynamic feature which allows you to declare a variable as dynamic and bypass the compile time checks.You can do any operation and access any member of a dynamic variable at compile time without getting any error.But if you access a member that don't exists you will get a RuntimeBinderException at runtime.
This can be useful in some cases, for example you can create a method that takes string type name as parameter, get the type using Type.GetType method and use Convert.ChangeType method to change type of your object, and assign the result to a dynamic variable. That way you can perform any operation on your dynamic object but you should be careful.BTW,even though this is possible, it is not a preferable way.

Related

How to create separated class that detect if the global int is certain number, and then overwrites label.text in my form?

I want to create global class(So I have to write it only once, not in all forms )that should detect if the global int is certain number and then overwrite text in label that says what is wrong.
For example when your name is too short it will says that your name is too short.
I know that you can do this in form, but I want whole new separated class because I plan to do this for 3 forms, so I would have to copy and paste the same errors etc... in each of them.
example:
Code in form register_menu.cs
public void getErrorNumber()
{
if (char_amount_username < 3 || textBox_username.Text == "Username")
{
Variables.error_number = 1;
}
else if (email_adress.Contains("#") != true || textBox_emailadress.Text == "Email adress")
{
Variables.error_number = 2;
}
else if (char_amount_password < 7 || textBox_password.Text == "Password")
{
Variables.error_number = 3;
}
else if (textBox_password.Text != textBox_passwordconfirm.Text)
{
Variables.error_number = 4;
}
else
{
Variables.error_number = 0;
}
}
private void button1_Click_1(object sender, EventArgs e)
{
ErrorCheck();
}
Code in class named GlobalErrorChecker.cs
namespace Xenious
{
internal class ErrorVariable
{
public static int error_number;
public void ErrorCheck()
getErrorNumber();
{
if (ErrorVariable.error_number is 1) ;
{
register_menu.error_msg.Text = "Your username is invalid!\n ⬤ Username must be avaiable\n ⬤ Minimum lenght of username is 4 ";
register_menu.displayERROR(true);
}
if(ErrorVariable.error_number is 2);
{
register_menu.error_message.Visible = true;
register_menu.error_msg.Text = "Your password is invalid!\n ⬤ Minimum lenght of password is 8 ";
register_menu.ICON_password_error.Visible = true;
}
if (ErrorVariable.error_number is 6) ;
{
login_menu.error_message.Visible = true;
login_menu.error_msg.Text = "Your username and password do not match!";
login_menu.ICON_username_error.Visible = true;
login_menu.ICON_password_error.Visible = true;
}
}
}
}
This is just example code how I want to do this, I have multiple problems.
First problem is that class GlobalErrorChecker.cs doesnt detect any controls from forms at all. I tried to fix this by looking online but I could find anything.
Second problem is that it says register_menu.ICON_password_error is unavaiable due to protection error CS0122....
I tried quite a huge amount of different methods how to do this, but I only found how to do this between 2 diffent forms, not between form and new class
Consider using a validation library like FluentValidation.
First create a class with properties to validate e.g.
public class Person
{
public string UserName { get; set; }
public string EmailAddress { get; set; }
public string Password { get; set; }
public string PasswordConfirmation { get; set; }
}
Create a validator.
public class PersonValidator : AbstractValidator<Person>
{
public PersonValidator()
{
RuleFor(person => person.UserName)
.NotEmpty()
.MinimumLength(3);
RuleFor(person => person.EmailAddress).EmailAddress();
RuleFor(person => person.Password.Length).GreaterThan( 7);
RuleFor(person => person.Password).Equal(p => p.PasswordConfirmation);
}
}
Create a new instance of the class, in this case Person. Populate values from your controls and than perform validation via Validate off the PersonValidator.
Below is a mock-up which uses StringBuilder to create a string which can be presented to the user.
Person person = new Person()
{
UserName = "billyBob",
Password = "my#Password1",
EmailAddress = "billyBob#gmailcom",
PasswordConfirmation = "my#Password1"
};
PersonValidator validator = new PersonValidator();
ValidationResult result = validator.Validate(person);
if (result.IsValid)
{
// person is valid
}
else
{
StringBuilder builder = new StringBuilder();
foreach (var error in result.Errors)
{
builder.AppendLine(error.ErrorMessage);
}
}
Dig in to ValidationResult if you need to inspect individual errors like PropertyName (Name of the property being validated) and ComparisonValue (Value that the property should not equal).
Note The email address validator only checks if an email address has a # so if you need more custom work is needed.
Making a static Extension Method
is one way to "create global class (so I have to write it only once...)". This answer will explore this option step-by-step.
First ask "what info is needed to determine a valid form?" Define these requirements in an interface:
interface IValidate
{
// Inputs needed
public string Username { get; }
public string Email { get; }
public string Password { get; }
public string Confirm { get; }
}
Now declare an Extension Method for "any" form that implements IValidate (this is the global class you asked about).
static class Extensions
{
public static int ValidateForm(this IValidate #this, CancelEventArgs e)
{
if (#this.Username.Length < 3) return 1;
if (!#this.Email.Contains("#")) return 2;
if (#this.Password.Length < 7) return 3;
if (!#this.Password.Equals(#this.Confirm)) return 4;
return 0;
}
}
The Form classes will be able to call the extension using this.
var e = new new CancelEventArgs();
int error_number = this.ValidateForm(e);
Example of Form Validation
For each of your 3 forms, implement the interface. This just means that the 3 form classes are making a promise or contract to provide the information that the interface requires (in this case by retrieving the text from the textboxes).
public partial class MainForm : Form, IValidate
{
#region I M P L E M E N T I N T E R F A C E
public string Username => textBoxUsername.Text;
public string Email => textBoxEmail.Text;
public string Password => textBoxPassword.Text;
public string Confirm => textBoxConfirm.Text;
#endregion I M P L E M E N T I N T E R F A C E
.
.
.
}
Then call the extension method when any textbox loses focus or receives an Enter key.
public partial class MainForm : Form, IValidate
{
public MainForm()
{
InitializeComponent();
foreach (Control control in Controls)
{
if(control is TextBox textBox)
{
textBox.TabStop = false;
textBox.KeyDown += onAnyTextboxKeyDown;
textBox.Validating += onAnyTextBoxValidating;
textBox.TextChanged += (sender, e) =>
{
if (sender is TextBox textbox) textbox.Modified = true;
};
}
}
}
private void onAnyTextBoxValidating(object? sender, CancelEventArgs e)
{
if (sender is TextBox textBox)
{
// Call the extension method to validate.
ErrorInt #int = (ErrorInt)this.ValidateForm(e);
if (#int.Equals(ErrorInt.None))
{
labelError.Visible = false;
buttonLogin.Enabled = true;
return;
}
else if (textBox.Modified)
{
buttonLogin.Enabled = false;
BeginInvoke(() =>
{
switch (#int)
{
case ErrorInt.Username: textBoxUsername.Focus(); break;
case ErrorInt.Email: textBoxEmail.Focus(); break;
case ErrorInt.Password: textBoxPassword.Focus(); break;
case ErrorInt.Confirm: textBoxConfirm.Focus(); break;
}
labelError.Visible = true;
labelError.Text = typeof(ErrorInt)
.GetMember(#int.ToString())
.First()?
.GetCustomAttribute<DescriptionAttribute>()
.Description;
textBox.Modified = false;
textBox.SelectAll();
});
}
}
}
private void onAnyTextboxKeyDown(object? sender, KeyEventArgs e)
{
if (sender is TextBox textbox)
{
if (e.KeyData.Equals(Keys.Return))
{
// Handle the Enter key.
e.SuppressKeyPress = e.Handled = true;
MethodInfo? validate = typeof(TextBox).GetMethod("OnValidating", BindingFlags.Instance | BindingFlags.NonPublic);
CancelEventArgs eCancel = new CancelEventArgs();
validate?.Invoke(textbox, new[] { eCancel });
}
}
}
.
.
.
}
Where:
enum ErrorInt
{
None = 0,
[Description("Username must be at least 3 characters.")]
Username = 1,
[Description("Valid email is required.")]
Email = 2,
[Description("Password must be at least 7 characters.")]
Password = 3,
[Description("Passwords must match.")]
Confirm = 4,
}

Access Parent Form from a UserControl

I have these properties on a form.
public enum LanguageID
{
en, fr, de, it, ro
}
[Browsable(false)]
public Language[] Languages = new Language[]()
{
new Language { LangID = LanguageID.en, TranslatedText = "One" },
new Language { LangID = LanguageID.fr, TranslatedText = "Un"},
new Language { LangID = LanguageID.de, TranslatedText = "Einer"}
// and so on, for all other languages
}
public class Language
{
public LanguageID LangID { get; set; } = LanguageID.en;
public string TranslatedText { get; set; } = "One";
}
In design-time, user can change LanguageID property.
I added some custom Control objects on my form. In those objects constructors I want to access form's public property Languages, to be able to set a property of my custom controls according to selected LanguageID from form's property.
I've tried the solution from this post, but Site property will be set only in design-time, not in runtime. In runtime Site property is null.
public ContainerControl ContainerControl
{
get { return _containerControl; }
set { _containerControl = value; }
}
private ContainerControl _containerControl = null;
// Custom object constructor
public MyControl()
{
var langID = ((Form)ContainerControl).LanguageID; // the problem is here, ContainerControl is populated in DesignMode, but not in runtime. In runtime it's value is null
var selectedLang = Array.Find(Form.Languages, l => l.LangID = langID);
// code to set text here
}
public override ISite Site
{
get { return base.Site; }
set
{
base.Site = value;
if (value == null)
{
return;
}
IDesignerHost host = value.GetService(
typeof(IDesignerHost)) as IDesignerHost;
if (host != null)
{
IComponent componentHost = host.RootComponent;
if (componentHost is ContainerControl)
{
ContainerControl = componentHost as ContainerControl;
}
}
}
}
If this is not the good approach, please, I need some advice.
Each controller has a parent object and you can use the following code to get the form:
Type type = this.Parent.GetType();
Control x = this.Parent;
while (type.BaseType.Name != "Form")
{
x = x.Parent;
type = x.GetType();
}
// HERE x is your form
Or as a method:
public Form GetParentForm()
{
Type type = this.Parent.GetType();
Control x = this.Parent;
while (type.BaseType.Name != "Form")
{
x = x.Parent;
type = x.GetType();
}
return (Form)x;
}
The loop is needed because your control might be inside another container inside of the form.

Is it possible to clear objects with the get property after calling the class?

this below to sample code;
private ExampleStatus _status;
public ExampleStatus status
{
get
{
if (_status == null) _status = new ExampleStatus();
//if (_status.receivedData) _status.receivedData = false; //this line is incorrect !
return _status;
}
}
public class ExampleStatus
{
public int Id { get; set; }
public string Name { get; set; }
public bool receivedData { get; set; }
//I don't want to use this method
public void Clear()
{
Id = 0;
Name = string.Empty;
receivedData = false;
}
}
int stateType = 0;
void ContinuousLoop(ExampleStatus statusObj)
{
while (true)
{
//I don't want to use the options below
//statusObj.Clear();
//or
//statusObj = new ExampleStatus();
if (stateType == 0)
{
statusObj.Id = 0;
statusObj.Name = "Firs Status";
}
else if (stateType == 1)
{
statusObj.Id = 1;
statusObj.Name = "Second Status";
statusObj.receivedData = true;
}
else if (stateType == 2)
{
statusObj.Id = 2;
statusObj.Name = "Third Status";
}
}
}
void RunThread()
{
var t1 = new Thread(() =>
{
ContinuousLoop(status);
});
t1.Start();
}
Is it possible to set default values ​​without a method or new instance, as shown in the example?
Actually that's why I'm asking this question:
I will use the class I have defined in many places. I will need to add a block of code, such as the Clear method, to every place I use it.
I'm also curious about one more thing. If I assign a new instance every time to reset my objects, does this cause problems in memory?
I know more or less how garbage collections work. However, they say that in practice it does not work as said in theory.
So if I add "IDisposable" to my Class, it would tell the garbage collector: Welcome, I'm a litter. Will you take me too?

WPF MVVM Control that connects to Web API

I have an ASP.NET Web API with SQL Database / Entity Framework that I will be using as the server side of an application that I am building. The client side will be WPF for now. I am having some trouble determining the best method for the MVVM controls to access the data from the server. All of the tutorials and courses I have done for MVVM connect directly to a local database, and they update when the control is loaded. What I want is a constant loop where the API is called once per minute and the data in the control automatically refreshed at that point. I have this working for the two main controls (ran into a problem updating the collection from a different thread and had to use App.Current.Dispatcher.Invoke), however I am not sure if I am keeping to best practice running the API calls directly from the view model. Also, I need to be able to share data between the view models.
ScheduledForwardsViewModel has data that ActiveForwardsViewModel needs, and ActiveForwardsViewModel has data that CreateForwardsViewModel needs. The ActiveForward for each entry needs to be able to see the scheduled date for each corresponding scheduled item so it can find the next event and display the time left until that event occurs in the ActiveForwardsView. The CreateForwardView simply needs access to the AllUsers,AllGroups,AllContacts observable collections created during the ActiveForwards data manipulation so it can use that data in the drop down fields when scheduling a new forward. I haven't been able to get the dropdowns to work yet. I do have access to the info I need from ScheduledForwardsView using a static object, but I feel like there may be a better way. I would prefer to refrain from making multiple calls to the API for the same data when part of my app already has the data I need.
Basic Layout:
MainWindow
CreateForwardView (with view model)
[Drop down boxes to select user and schedule forward]
[Buttons, etc.]
[TabControl]
[TabItem: Active Forwards]
ActiveForwardsView (with view model)
[TabItem: Scheduled Forwards]
ScheduledForwardsView (with view model)
[EndTabControl]
The ActiveForwardsViewModel is below. The ScheduledForwardsViewModel is essentially the same thing, but it calls a different API method and contains a static object that I am using in ActiveForwardsViewModel (see the part where I wait for ScheduledForwardsViewModel to complete 1 run before I continue with UpdateUserObjects). That didn't seem like the right way to do it, but I set it up that way just so I could move onto other things.
public class ActiveForwardsViewModel : INotifyPropertyChanged
{
private CancellationToken updater = default(CancellationToken);
private AppLog log;
private FFObject _selectedObject;
private ObservableCollection<FFObject> _activeForwards;
public ObservableCollection<FFObject> ActiveForwards
{
get { return _activeForwards; }
set
{
if (_activeForwards != value)
{
_activeForwards = value;
PropertyChanged(this, new PropertyChangedEventArgs("ActiveForwards"));
}
}
}
public ObservableCollection<FFObject> AllUsers { get; set; }
public ObservableCollection<FFObject> AllGroups { get; set; }
public ObservableCollection<FFObject> AllContacts { get; set; }
public ObservableCollection<FFObject> AllObjects { get; set; }
public bool Running = false;
public bool FirstRunComplete = false;
public event PropertyChangedEventHandler PropertyChanged = delegate { };
public ActiveForwardsViewModel()
{
if (DesignerProperties.GetIsInDesignMode(new System.Windows.DependencyObject()))
{
updater.ThrowIfCancellationRequested();
return;
}
ActiveForwards = new ObservableCollection<FFObject>();
AllUsers = new ObservableCollection<FFObject>();
AllGroups = new ObservableCollection<FFObject>();
AllContacts = new ObservableCollection<FFObject>();
AllObjects = new ObservableCollection<FFObject>();
StartUpdater(updater);
RemoveForwardCommand = new RelayCommand(OnRemove, CanRemove);
}
public async Task StartUpdater(CancellationToken token = default(CancellationToken))
{
while (!token.IsCancellationRequested)
{
Running = true;
await this.Update();
FirstRunComplete = true;
try
{
await Task.Delay(TimeSpan.FromMinutes(1), token);
}
catch (TaskCanceledException)
{
Running = false;
break;
}
}
}
private List<FFObject> UpdateAllObjectList(string strJson)
{
var serializer = new JavaScriptSerializer();
return serializer.Deserialize<List<FFObject>>(strJson);
//return AllObjects;
}
public string GetString(string method)
{
using (var client = new WebClient())
{
var url = string.Format("https://mywebapi.domain.com/api/{0}", method);
return client.DownloadString(url);
}
}
public async Task Update()
{
Func<string, List<FFObject>> getUsersJson = UpdateAllObjectList;
await Task<string>.Factory.StartNew(() => GetString("Users"))
.ContinueWith(antecendent => getUsersJson(antecendent.Result))
.ContinueWith(antecendent => UpdateUserObjects(antecendent.Result));
}
private void CheckRemoved(List<FFObject> all)
{
List<FFObject> RemoveObjects = new List<FFObject>();
foreach (var obj in ActiveForwards)
{
var newObj = all.FirstOrDefault(i => i.ID == obj.ID);
if (newObj == null)
{
RemoveObjects.Add(obj);
}
else
{
if (!(bool) newObj.IsForwarded)
{
RemoveObjects.Add(obj);
}
}
}
foreach (var obj in RemoveObjects)
{
App.Current.Dispatcher.Invoke((Action)delegate
{
ActiveForwards.Remove(obj);
});
}
}
private void UpdateUserObjects(List<FFObject> all)
{
Debug.WriteLine("Starting UpdateUserObject");
if (all != null)
{
AllObjects = new ObservableCollection<FFObject>(all);
CheckRemoved(all);
var x = 0;
while (!ScheduledForwardsViewModel.RunOnce && x < 5)
{
System.Threading.Thread.Sleep(1000);
x++;
}
foreach (var obj in all)
{
if (obj.ObjectType.ToLower() == "user")
{
var existing = AllUsers.FirstOrDefault(i => i.DistinguishedName == obj.DistinguishedName);
if (existing != null)
{
existing.ForwardedTo = obj.ForwardedTo;
existing.ForwardedToAd = obj.ForwardedToAd;
existing.ForwardedToDn = obj.ForwardedToDn;
existing.ForwardedToPk = obj.ForwardedToPk;
existing.ForwardedToDisplay = obj.ForwardedToDisplay;
existing.IsForwarded = obj.IsForwarded;
existing.DeliverAndRedirect = obj.DeliverAndRedirect;
existing.IsScheduled = obj.IsScheduled;
existing.TimeLeft = obj.TimeLeft;
}
else
{
//AllUsers.Add(obj);
App.Current.Dispatcher.Invoke((Action)delegate // <--- HERE
{
AllUsers.Add(obj);
});
}
if (obj.IsForwarded ?? false)
{
existing = ActiveForwards.FirstOrDefault(i => i.DistinguishedName == obj.DistinguishedName);
obj.TimeLeft = "";
var now = DateTime.Now;
var TimeRemaining = new TimeSpan?();
foreach (var schedule in ScheduledForwardsViewModel.ScheduledForwards)
{
if (schedule.DistinguishedName == obj.DistinguishedName)
{
if (schedule.StopJobStatus == "Scheduled")
{
if (TimeRemaining == null)
{
TimeRemaining = schedule.StopTime - now;
}
else
{
if (schedule.StopTime - now < TimeRemaining)
{
TimeRemaining = schedule.StopTime - now;
}
}
}
}
}
if (TimeRemaining != null)
{
var remaining = (TimeSpan)TimeRemaining;
var min = new int();
if (remaining.Seconds > 30)
{
min = remaining.Minutes + 1;
}
double m = remaining.Minutes / (double)60;
double hm = remaining.Hours + m;
double h = hm / 24;
double dh = remaining.Days + h;
if (remaining.Days > 0)
{
var daysleft = Math.Round(dh, 2);
var quarterRound = Math.Round(dh * 4, MidpointRounding.ToEven) / 4;
obj.TimeLeft = quarterRound + "d";
}
else if (remaining.Hours > 0)
{
var hoursleft = Math.Round(hm, 2);
var quarterRound = Math.Round(hm * 4, MidpointRounding.ToEven) / 4;
obj.TimeLeft = quarterRound + "h";
obj.TimeLeft = remaining.Hours + "h" + remaining.Minutes + "m";
}
else
{
if (min == 0)
{
obj.TimeLeft = "< 30s";
}
else
{
obj.TimeLeft = min + "m";
}
}
}
if (existing != null)
{
existing.ForwardedTo = obj.ForwardedTo;
existing.ForwardedToAd = obj.ForwardedToAd;
existing.ForwardedToDn = obj.ForwardedToDn;
existing.ForwardedToPk = obj.ForwardedToPk;
existing.ForwardedToDisplay = obj.ForwardedToDisplay;
existing.IsForwarded = obj.IsForwarded;
existing.DeliverAndRedirect = obj.DeliverAndRedirect;
existing.IsScheduled = obj.IsScheduled;
existing.TimeLeft = obj.TimeLeft;
}
else
{
//ActiveForwards.Add(obj);
App.Current.Dispatcher.Invoke((Action)delegate // <--- HERE
{
ActiveForwards.Add(obj);
});
}
}
}
else if (obj.ObjectType.ToLower() == "group")
{
if (obj.IsForwarded ?? false)
{
var existing = AllGroups.FirstOrDefault(i => i.DistinguishedName == obj.DistinguishedName);
if (existing != null)
{
existing.ForwardedTo = obj.ForwardedTo;
existing.ForwardedToAd = obj.ForwardedToAd;
existing.ForwardedToDn = obj.ForwardedToDn;
existing.ForwardedToPk = obj.ForwardedToPk;
existing.ForwardedToDisplay = obj.ForwardedToDisplay;
existing.IsForwarded = obj.IsForwarded;
existing.DeliverAndRedirect = obj.DeliverAndRedirect;
existing.IsScheduled = obj.IsScheduled;
existing.TimeLeft = obj.TimeLeft;
}
else
{
//AllGroups.Add(obj);
App.Current.Dispatcher.Invoke((Action)delegate // <--- HERE
{
AllGroups.Add(obj);
});
}
}
}
else if (obj.ObjectType.ToLower() == "contact")
{
if (obj.IsForwarded ?? false)
{
var existing = AllContacts.FirstOrDefault(i => i.DistinguishedName == obj.DistinguishedName);
if (existing != null)
{
existing.ForwardedTo = obj.ForwardedTo;
existing.ForwardedToAd = obj.ForwardedToAd;
existing.ForwardedToDn = obj.ForwardedToDn;
existing.ForwardedToPk = obj.ForwardedToPk;
existing.ForwardedToDisplay = obj.ForwardedToDisplay;
existing.IsForwarded = obj.IsForwarded;
existing.DeliverAndRedirect = obj.DeliverAndRedirect;
existing.IsScheduled = obj.IsScheduled;
existing.TimeLeft = obj.TimeLeft;
}
else
{
//AllContacts.Add(obj);
App.Current.Dispatcher.Invoke((Action)delegate // <--- HERE
{
AllContacts.Add(obj);
});
}
}
}
else
{
throw new NotImplementedException();
}
}
}
RunOnce = true;
}

Devexpress DxValidateProvidor validate

I want to check whether the value entered in a DevExpress Control is empty, but my Validation always returns false. For this reason, I am unable to perform further operations.
If you can help I'd appreciate it.
public static class ValidateHelpers {
public static bool validate(Form f, params Control[] control) {
bool result = true;
if (control != null) {
KgsDxValidationProvider prov = new KgsDxValidationProvider { ValidationMode = ValidationMode.Auto };
ConditionValidationRule notEmptyValidationRule = new ConditionValidationRule {
ConditionOperator = ConditionOperator.IsNotBlank,
ErrorText = "You Must Enter A Value",
ErrorType = ErrorType.Critical
};
foreach (var item in control) {
prov.SetValidationRule(item, notEmptyValidationRule);
result = false;
}
f.ValidateChildren();
}
return result;
}
}
You don't need to validate all childrens on your form. This will do what you want:
private bool Validate(params Control[] controls)
{
bool result = controls == null || !controls.Any();
if (controls != null)
{
DXValidationProvider provider = new DXValidationProvider { ValidationMode = ValidationMode.Auto };
ConditionValidationRule noEmptyValues = new ConditionValidationRule
{
ConditionOperator = ConditionOperator.IsNotBlank,
ErrorText = #"You must enter a value",
ErrorType = ErrorType.Critical
};
foreach (Control control in controls)
{
provider.SetValidationRule(control, noEmptyValues);
}
result = provider.Validate(); //Validate all controls associated with the provider
}
return result;
}
If you need further assistance for custom validation etc. you can check this link.

Categories