I have a custom control that print the current date into the page.
The control has a Format property for setting witch DateTime property to be printed. (Date, Day, Year etc...)
<TSC:DateTimeWriter runat="server" Format="Year" />
But what i want is when i type :
Format="
I want to show a list of all the possible values(Using Visual Studio).
The cs code:
public class DateTimeWriter : Control
{
public string Format { get; set; }
protected override void Render(HtmlTextWriter writer)
{
writer.Write(writeDateTime());
}
private string writeDateTime()
{
var now = DateTime.Now;
switch (Format)
{
case "Year":
return now.Year.ToString();
case "Day":
return now.Day.ToString();
etc...
default:
return now.ToString();
}
}
}
If you make the Format property an enum instead of a string, VS will be able to display a list of supported formats. E.g.:
public enum DateTimeFormat
{
Year,
...
}
Create an enumerated Type
namespace YourNameSpace
{
[Serializable()]
public enum DateFormat
{
Date,
Day,
Year
}
}
then add a property to your control:
/// <summary>
/// Date Format
/// </summary>
public DateFormat DateFormat
{
get
{
if (ViewState["DateFormat"] == null || ViewState["DateFormat"].ToString().Trim() == String.Empty)
{
return DateFormat.Date; //Default
}
return (DateFormat)ViewState["DateFormat"];
}
set
{
ViewState["DateFormat"] = value;
}
}
Related
I have a datagrid in my xamarin form app and it got a editable column. The values in the column are from MySql database and user can change the value and store to db. I used IPropertyChanged interface to allow user make the changes to the value. There is one condition when editing the value. The new value must be equal or bigger than the original value. My problem is whenever I enter a value bigger than the original, I cannot edit the value again to previous value. For example, the original value is 10. The new value I enter is 30. If I want to change the value again and this time I set it to 20, it is not allowing me because now the original value is 30 not 10 and 20 is less than 30. How can I retain the original value and compare with it?
public int ActualReading
{
get
{
return _ActualReading;
}
set
{
if (value >= _ActualReading)
{
_ActualReading = value;
RaisePropertyChanged("ActualReading");
}
else
{
UserDialogs.Instance.Alert("Meter readings should not be smaller than previous value.","Error","Ok");
}
}
}
private void RaisePropertyChanged(String Name)
{
if (PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs(Name));
}
You have to store the original value. I'm using the following pattern.
Assuming you have a model like this
public class Model
{
public int ActualReading {get; set;}
}
and a viewmodel like this (I removed the INotifyPropertyChanged part for better reading)
public class ViewModel
{
private readonly Model MyModel;
private int _actualReading;
public int ActualReading
{
get { return _actualReading; }
set { _actualReading = value; }
}
public ViewModel(Model model)
{
MyModel = model;
ActualReading = model.ActualReading;
}
public Model GetModel()
{
MyModel.ActualReading = ActualReading;
return MyModel;
}
}
When you create the ViewModel instances you initialize it with the coresponding Model instance. When you have implemented this you can add your check in an easy way like this.
private int _actualReading;
public int ActualReading
{
get { return _actualReading; }
set
{
if (value >= MyModel.ActualReading)
{
_actualReading = value;
}
else
{
UserDialogs.Instance.Alert("Meter readings should not be smaller than previous value.", "Error", "Ok");
}
}
}
My class has a property that looks like this:
public string DueDateAsString
{
get
{
DateTime duedate = this.RigActionType.FrequencyType.GetDueDateForAction(this);
if (this.HasBeenCompleted(duedate))
{
return "Completed";
}
else if (DateTime.Compare(DateTime.Today, duedate) > 0) // past due
{
return duedate.ToString() + " (past due)";
}
return duedate.ToString();
}
}
I would like to extend the functionality a bit more so that this could also return something like "due in n days" but in a way that I don't have to create a separate property called VerboseDueDateAsString (or something).
Is it possible to do something like this:
someObject.DueDateAsString; // Outputs "4/1/2014"
someObject.DueDateAsString.Verbose; // Outputs "Due in x days"
You could expose the due date as a property and create an extension method for the conversion. Place it in a static class whose namespace is visible where you need it.
public static string Verbose(this DateTime date)
{
return String.Format("Due in {0} days", (DateTime.Now - date).Days);
}
Then apply it directly to the due date
Console.WriteLine(someObject.DueDate.Verbose());
If you replace your actual property with a similar exetension method you will get a consitent way of displaying due dates
public static string Concise(this DateTime date)
{
// Place the logic of DueDateAsString here
}
Console.WriteLine(someObject.DueDate.Concise());
DueDateAsString doesn’t really seem like it should be a property in the first place.
struct DueDate {
DateTime date;
bool completed;
public DueDate(DateTime date, bool completed) {
this.date = date;
this.completed = completed;
}
public override string ToString() {
if (this.completed) {
return "Completed";
}
if (DateTime.Compare(DateTime.Today, duedate) > 0) // past due
{
return duedate.ToString() + " (past due)";
}
return duedate.ToString();
}
public string ToVerboseString() {
// Implement this
}
}
⋮
public DueDate DueDate
{
get
{
DateTime duedate = this.RigActionType.FrequencyType.GetDueDateForAction(this);
return new DueDate(duedate, this.HasBeenCompleted(duedate));
}
}
You could use an extension method on DateTime, but then there’s still the matter of determining whether it’s completed or not.
Name it something other than DueDate, by the way.
DueDateAsString would need to be an object that itself contains a Verbose method afaik
i make user control from 3 text boxes but i don not how to declare read only property to it i tried many things but it do not work here is my code to make the control
i want to make it read only when needed like if i add checkbox i want if checkbox.check=true make my control readonly
public partial class dateIN : UserControl
{
Dates datess = new Dates();
public dateIN()
{
InitializeComponent();
}
private void dateIN_Leave(object sender, EventArgs e)
{
if (txtDay.Text != "" || txtMonth.Text != "" || txtYear.Text != "")
{
if (!datess.IsHijri(txtDay.Text.Trim() + "/" + txtMonth.Text.Trim() + "/" + txtYear.Text.Trim()))
{
txtDay.Focus();
}
}
}
public string Day
{
set { txtDay.Text = value; }
get { return txtDay.Text; }
}
public string Month
{
set { txtMonth.Text = value; }
get { return txtMonth.Text; }
}
public string Year
{
set { txtYear.Text = value; }
get { return txtYear.Text; }
}
need to know how to make read only property available here plz
just remove the set { } part of the property
Example:
public string Day
{
get { return txtDay.Text; }
}
I dont know the correlation of where your "txtDay", "txtMonth", "txtYear" come from, but you could do something like
public partial class dateIN : UserControl
{
...
...
private bool AllowEditing()
{ return SomeCondition when SHOULD be allowed...; }
public string Day
{
// only allow the set to apply the change if the "AllowEditing" condition
// is true, otherwise, ignore the attempt to assign.
set { if( AllowEditing() )
txtDay.Text = value; }
get { return txtDay.Text; }
}
// same concept for month and year too
}
so may you add some flag to your set when it is true then you set a value.
also you can work with textbox property called ReadOnly.
This is my custom textBox:
public class TextBoxInputNumbers : TextBox
{
Regex regex;
public enum DatatypesInput
{
Integer, Decimals
}
public TextBoxInputNumbers()
{
DatatypeInput = DatatypesInput.Integer;
}
public DatatypesInput DatatypeInput
{
set
{
switch (value)
{
case DatatypesInput.Integer:
regex = new Regex("[^0-9.-]+");
break;
case DatatypesInput.Decimals:
regex = new Regex("[^0-9-]+");
break;
}
}
}
protected override void OnPreviewTextInput(System.Windows.Input.TextCompositionEventArgs e)
{
e.Handled = regex.IsMatch(e.Text);
}
}
And I'd like to show the property DatatypeInput in XAML, but they cannot recognize any element of my enum.
You can convert the enun name to a string using the Enum.GetName() method:
get
{
return Enum.GetName(typeof(DatatypesInput), value);
}
and then bind to that value in your XAML.
Is that what you are looking for? Use Enum.GetNames() is you need the list of all valid names.
I have a question regarding inheritance, so I will describe the scenario below:
I am reading a text file containing logs. (One log per line)
Each log-line will have the following format:
"Date Type Description"
However, depending on the "Type" of log, I will have to parse the "Description" differently and pull out different fields.
Here are some examples:
5/1/2011 Information Field1, Field2, Field3
5/2/2011 Error Field1
--
So, what I tried to do was this:
-Get a line out of the log
-Parse it according to the pattern "Date Type Description"
-Look at the "Type" field, and create new objects/parse description as necessary
public class Log
{
public DateTime Date;
public String Type;
public String Description;
public Log(String line)
{
this.Date = GetDate();
this.Type = GetType();
this.Description = GetDescription();
}
}
public class InformationLog : Log
{
public String Field1;
public String Field2;
public String Field3;
public InformationLog(Log log)
{
this.Field1 = GetField1(log.Description);
this.Field1 = GetField2(log.Description);
this.Field1 = GetField3(log.Description);
}
}
public class Client
{
public void Main()
{
String line = ReadFileAndGetLine(); // Get a line from the file
Log log = new Log(line);
if(log.Type == "Information")
log = new InformationLog(log); // Is this right?
}
}
This works how I want it to, but it seems like this cannot be a good practice. The "log" variable is using itself as a parameter to its own constructor.
My question is:
Is there a standard way of doing this? Or, is there anything wrong with this implemenation?
--
Edit:
Also, I should mention: My reasoning was that I would parse the line once to get out the date and type, and then parse it again to get the finer details.
I decided to use inheritance so I wouldn't have to parse out the Date and Type fields twice.
Try to use Factory pattern
static class LogFactory
{
public static Log Create(String line)
{
if(GetType(line) == "Information")
return CreateInformationLog(line);
return CreateLog(line);
}
private static Log CreateLog(String line)
{
return new Log(line);
}
private static Log CreateInformationLog(String line)
{
return new InformationLog(line);
}
}
And then try to use
String line = ReadFileAndGetLine(); // Get a line from the file
Log log = LogFactory.Create(line);
As per my comment, why not just do something a little like this:
public enum LogEntryType
{
Error = -1,
Information = 0,
}
public class LogEntry
{
public string Raw;
public DateTime Date;
public LogEntryType Type;
public string Description;
public LogEntry(String line)
{
Raw = line;
Date = ParseDate();
Type = ParseType();
Description = ParseDescription();
}
public string ParseDescription()
{
var result = string.Empty;
switch(Type)
{
case LogEntryType.Error:
//parse here
break;
case LogEntryType.Information:
//parse here
break;
}
return result;
}
}
I notice you have fields in the derivative class, but the description could be parsed here; though, I can see why people may want to shift it to the place that actually knows how the description should be parsed, in which case you could use a factory pattern suggested in another answer, or implement a 'property bag' type scenario - but drifting away from strong typing is generally frowned upon these days, I reckon.
Another suggestion, though very similar to your initial attempt, tends to encapsulate management of the types, as opposed to having a detached class handle such stuff - a pattern a little (superficially) like Exception where you have a root entry and inner entries:
public enum LogEntryType
{
Error = -1,
Information = 0,
}
public class LogEntry
{
public string Raw;
public DateTime Date;
public LogEntryType Type;
public string Description;
public InnerLogEntry InnerEntry;
public LogEntry(String line)
{
Raw = line;
Date = ParseDate();
Type = ParseType();
//parse the 'raw' description...
Description = ParseDescription();
//determine the inner entry type...
switch (Type)
{
case LogEntryType.Error:
InnerEntry = new ErrorLogEntry(this);
break;
case LogEntryType.Information:
InnerEntry = new InformationLogEntry(this);
break;
}
}
}
public abstract class InnerLogEntry
{
protected LogEntry Parent;
public InnerLogEntry(LogEntry logEntry)
{
Parent = logEntry;
}
}
public class InformationLogEntry : InnerLogEntry
{
public InformationLogEntry(LogEntry logEntry)
: base(logEntry)
{
//parse custom data
}
}
public class ErrorLogEntry : InnerLogEntry
{
public ErrorLogEntry(LogEntry logEntry)
: base(logEntry)
{
//parse custom data
}
}