set value for the built in properties episerver, StopPublish - episerver

Im trying to enforce the user to set a DateTime for StopPublish
[Required]
public virtual DateTime EnforceStopPublish
{ get; set; }
public override DateTime? StopPublish
{
get { return EnforceStopPublish; }
}
didn't work, is there another possible way, maybe by an Publishing event? example.
thanks in advance

Never tried it on the StopPublish property (not sure about any side-effects), but could you do it with standard data annotations, i.e. a Requiredattribute on your overriding property?

You could also do it in the SetDefaultValues method. The user will then of course be able to remove or change the stoppublishdate, but that can certanly be ok in a lot of cases.
public override void SetDefaultValues(ContentType contentType)
{
base.SetDefaultValues(contentType);
this[MetaDataProperties.PageStopPublish] = DateTime.Now.AddDays(5);
}

Related

Fill a combobox in WPF with a list of web services

I have a control like this:
<ComboBox x:Name="ComboTipo"
Height="23"
SelectionChanged="ComboTipo_SelectionChanged"
Width="450"
Canvas.Left="609"
Canvas.Top="26" />
And my code is:
ComboTipo.DisplayMemberPath = "Descripcion";
ComboTipo.SelectedValuePath = "IdTipoPersona";
ComboTipo.ItemsSource = myWebServices.dameTipos();
My web services returns a list for this object, this class is created in automatic when i add the reference to the web services:
public partial class TipoPersona {
private short idTipoPersonaField;
private string descripcionField;
/// <comentarios/>
public short IdTipoPersona {
get {
return this.idTipoPersonaField;
}
set {
this.idTipoPersonaField = value;
}
}
/// <comentarios/>
public string Descripcion {
get {
return this.descripcionField;
}
set {
this.descripcionField = value;
}
}
}
But the problem is:
The combobox displays the data types for each element of the list, and i want display the Descripcion.
Can you help me plis! Thanks
What does IdTipoPersona look like? Is it a class you created? If so, you may need to reference the property that you want displayed. It would look something like this:
ComboTipoPersona.SelectedValuePath = "IdTipoPersona.Text";
Where Text would be replaced by the property. It is really hard to judge otherwise what is going on with knowing a little more about the object structure that myWebServices.dameTipos() returns.
EDIT
Ok I was able to simulate your problem and simulate a solution as well.
Your issue is in the Tipos class. There are a couple of things necessary when binding to a combobox with a custom class.
First off, you will want to add accessors and mutators (getters and setters) to IdTippoPersona and Descripcion.
You should add a constructor that assigns to those properties with parameters.
It is usually a good idea to add a default constructor.
The finished code will look like this:
public class Tipos
{
public int IdTipoPersona { get; set; }
public string Descripcion { get; set; }
public Tipos(int id, string descripcion)
{
IdTipoPersona = id;
Descripcion = descripcion;
}
}
I found the asnwer if someone needs it.
We need create a class intermediate class but we were working with entity framework, for this way, we need add the intermediate class like complex type in my model (entity framework).
And also we need override this class.
And it works so well.
Thanks for all #Goody

Custom configuration properties - Entry has already been added

I'm developing a windows service that reads information from the app.config at start-up which should allow us to change internal thread configuration without redeploying the service.
I created some custom configuration sections and elements as follows (implementation omitted):
public class MyConfigurationSection
{
[ConfigurationProperty("threads")]
[ConfigurationCollection(typeof(MyThreadCollection), AddItemName="addThread")>
public MyThreadCollection threads { get; }
}
public class MyThreadCollection
{
protected override void CreateNewElement();
protected override object GetElementKey(ConfigurationElement element);
}
public class MyThreadElement
{
[ConfigurationProperty("active", DefaultValue=true, IsRequired=false)>
public bool active { get; set; }
[ConfigurationProperty("batchSize", DefaultValue=10, IsRequired=false)>
public int batchSize { get; set; }
[ConfigurationProperty("system", IsRequired=true)>
public string system { get; set; }
[ConfigurationProperty("department", IsRequired=true)>
public string department { get; set; }
[ConfigurationProperty("connection", IsRequired=true)>
public MyThreadConnectionElement connection { get; set; }
}
public class MyThreadConnectionElement
{
[ConfigurationProperty("server", IsRequired=true)>
public string server { get; set; }
[ConfigurationProperty("database", IsRequired=true)>
public string database { get; set; }
[ConfigurationProperty("timeout", DefaultValue=15, IsRequired=false)>
public int timeout { get; set; }
}
Then I add some elements to the app.config as follows:
<configurationSection>
<threads>
<addThread
active="True"
batchSize="50"
system="MySystem1"
department="Department1">
<connectionString
server="MyServer"
database="Database1" />
</addThread>
<addThread
active="True"
batchSize="30"
system="MySystem2"
department="Department2">
<connectionString
server="MyServer"
database="Database2" />
</addThread>
</threads>
</configurationSection>
Everything works - configuration is read, threads are created, and the processes run.
The problem is, I would like both these threads to have the same system name/value -- both should be MySystem -- but when I do that and run the program, I get a The entry 'MySystem' has already been added. exception.
I figured it might be because a property has to be explicitly configured to allow duplicates, but I don't know how and I couldn't find a property of the ConfigurationProperty class that might allow that, other than IsKey, but from its description it didn't seem like the answer, and trying it didn't solve the problem. Am I on the right track here?
Initially the system property was named name and I though that just maybe any property named name is treated as a unique identifier, so I changed it to system but it didn't change anything.
I tried the <clear /> tag as some other, similar posts suggested, without success.
Do I need to add another hierarchy to the configuration section -- Config -> Department -> Thread instead of Config -> Thread? I'd prefer to not take this approach.
Thanks for any and all input.
I actually found the problem and solution quite some time ago, but forgot to post the answer; thanks #tote for reminding me.
When implementing the ConfigurationElementCollection class, the GetElementKey(ConfigurationElement) method can be overridden. Without immediately realising what the method is for I overrode it and simply returned the system property value, and, since more than one configuration element had the same system name, technically they had the same key, which is why the error occurred.
The solution for me was to return the system and the department values as system.department which resulted in unique keys.

Validation of a combobox in Silverlight 4

I'm trying to understand how validation works for a combo box when its ItemsSource is bound to a ObserableCollection of complex types. I am using RIA as the serivce to connect the client tier to the middle tier. Also not sure if this makes a difference the combobox control is inside a dataform. I have done alot of reading on this and found this article to be the most useful: http://www.run80.net/?p=93
So firstly my entity: I have a field decorated like so:
[Required]
public virtual long FrequencyId { get; set; }
[Include]
[Association("TreatmentFrequencyToTreatmentRecordAssociation", "FrequencyId", "Id", IsForeignKey = true)]
public virtual TreatmentFrequency Frequency
{
get
{
return this.frequency;
}
set
{
this.frequency = value;
if (value != null)
{
this.FrequencyId = value.Id;
}
}
}
Now I belive that I cannot set the [Required] annotation on an association but instead on the foreign key id (what the above article says).
The actual Treatment Frequency class looks like this:
public class TreatmentFrequency
{
[Key]
public virtual long Id { get; set; }
[Required]
[StringLength(10)]
public virtual string Code { get; set; }
[Required]
[StringLength(40)]
public virtual string Name { get; set; }
public override bool Equals(object obj)
{
obj = obj as TreatmentFrequency;
if (obj == null)
{
return false;
}
return this.Id == ((TreatmentFrequency)obj).Id;
}
public override int GetHashCode()
{
return this.Name.GetHashCode();
}
}
I have overriden the Equals and GetHashCode method becuase in another article it said that when in a collection you need to override the equals to match on the key otherwise when you use SelectedItem although all the values would be the same between the item in the collection and the selecteditem they would be two different instances and thus not match with the default implementation of Equals.
Now my xaml looks like this:
<df:DataField Label="Frequency">
<ComboBox SelectedItem="{Binding Path=CurrentItem.Frequency, Mode=TwoWay}" ItemsSource="{Binding Path=Frequencies}" DisplayMemberPath="Name" SelectedValue="{Binding Path=CurrentItem.FrequencyId, Mode=TwoWay}" SelectedValuePath="Id"/>
</df:DataField>
To be honest the above doesn't make much sense to me, I could remove SelectedValue and SelectedValuePath and the form would still work as expected (without validation) I thought that Selected Value would point to the complex type E.g. CurrentItem.Frequency and then the SelectedValuePath would be the underlying "Name" property. However I also understand what the author is trying to do in that the [Required] tag isn't on the association but the foreign key id E.g. CurrentItem.FrequencyId, so it must have to go somewhere.
Now a final compelexity is that this form is part of a wizard so I am not able to validate the entire object, instead I manually have to validate certain field which are only being populated in this particular wizard step. To do this I created the method:
public void ValidateProperty(object value, string propertyName)
{
var results = new List<ValidationResult>();
Validator.TryValidateProperty(value, new ValidationContext(this.TreatmentRecord, null, null) { MemberName = propertyName }, results);
foreach (var error in results)
{
this.TreatmentRecord.ValidationErrors.Add(error);
}
}
In my view model I have a method IsValid which is called before the wizard is allowed to navigate to the next step and then I call the above method like so:
public bool IsValid
{
get
{
this.treatmentRecordWizardContext.ValidateProperty(this.treatmentRecordWizardContext.TreatmentRecord.Frequency, "Frequency");
this.treatmentRecordWizardContext.ValidateProperty(this.treatmentRecordWizardContext.TreatmentRecord.FrequencyId, "FrequencyId");
this.OnPropertyChanged(() => this.CurrentItem);
if (this.treatmentRecordWizardContext.TreatmentRecord.ValidationErrors.Count == 0)
{
return true;
}
return false;
}
}
With all of the above code the validation is completly ignored when the combobox is left empty. I have not templated the combobox itself so I am really at a loss as to why its not working and really which part of the solution is at fault, is it the bindings or is it the entitys in the RIA not defined correctly!
Hope someone can help I've spent far too long trying to get this to work, I assume this must be done reqularly by other developers so I'm hoping its a simple fix.
This was actually a simple problem in th end, I assumed that the [Required] annotation would check that the association was present and not null. It seems that all it actually does is check that in this case that FrequencyId is not null. And there was the problem in that I was using a long and not a nullable long (long?). Once I made the change to make them nullable the validation started working as expected even with the bindings which made no sense to me. If anyone could explain them that would be great!
Phil

What kind of compiler magic do we need more?

I develop lot view models which are:
1) All have to implement INotifyPropertyChanged to be bindable to UI.
2) Property setters have to raise PropertyChanged on change.
3) PropertyChanged event has to provide proper property name.
If you (like me) tied of writing something like this:
public string Name
{
get
{
return _name;
}
set
{
if (_name != value)
{
_name = value;
RaisePropertyChanged("Name");
}
}
}
Then refactor this method like this and sometimes forget to update property name literal:
string _fundName;
public string FundName
{
get
{
return _fundName;
}
set
{
if (_fundName != value)
{
_fundName = value;
RaisePropertyChanged("Name");
}
}
}
And then spend a day to debug why your UI is not refreshing and databinding doesn't work properly.
Then all we need is some kind of magic.
What if I just need to write this:
[Magic] // implicit transformation
public string FundName { get; set; }
or if I have many properties:
[Magic]
public class MyViewModel
{
public string FundName { get; set; }
public string FundType { get; set; }
[NoMagic] // suppress transformation
public int InternalId { get; set; }
}
So I have just developed a MSBuild task to do this magic after the build (http://kindofmagic.codeplex.com).
The question is, what kind of magical postprocessing would you like more?
Does automatic implementation of INotifyPropertyChanging makes sense?
Try this
http://code.google.com/p/notifypropertyweaver/
No attributes required
No references required
No base class required
Here is my blog article about it
http://codesimonsays.blogspot.com/2010/11/attempting-to-solve-inotifypropertychan.html
It supports the attributes you request
NotifyPropertyAttribute (notify for a property)
NotifyForAllAttribute (notify for all properties on a type)
NotifyIgnoreAttribute (do not notify for a property or type)
AlsoNotifyFor (Allows the injection of notify code that points to a different property)
Although these are option and designed for fine tuning. Most injection is done by convention through analyzing the existing IL.
If we're going to have fancy code generation, I think I would prefer a way to generate DependancyProperties more easily. The snippit I use is certainly helpful, but I'm not a fan how jumbled the code looks when you have on-changed and coerce callbacks, and metadata options. Maybe I'll try and mock up a sample after work.
Edit: Well, here's one concept. It would look a lot more clever if you pass anonymous methods to attributes, but it's still a step up.
Before:
[DpDefault("The Void")]
[DpCoerce(new CoerceValueCallback(MainWindow.CoerceAddress))]
[DpChanged(new PropertyChangedCallback(MainWindow.ChangeAddress1))]
[DpChanged(new PropertyChangedCallback(MainWindow.ChangeAddress2))]
[DpOptions(FrameworkPropertyMetadataOptions.Inherits)]
public string Address {
get { return Dp.Get<string>(); }
set {
if (Dp.Get<string>() != value) {
Dp.Set(value);
PostOffice.SendMailToTheBoss("I moved!");
}
}
}
After:
public string Address {
get { return (string)GetValue(AddressProperty); }
set {
if ((string)GetValue(AddressProperty) != value) {
SetValue(AddressProperty, value);
PostOffice.SendMailToTheBoss("I moved!");
}
}
}
public static readonly DependencyProperty AddressProperty =
DependencyProperty.Register("Address", typeof(string), typeof(MainWindow),
new FrameworkPropertyMetadata((string)"The Void",
FrameworkPropertyMetadataOptions.Inherits,
new PropertyChangedCallback(MainWindow.ChangeAddress1)
+ new PropertyChangedCallback(MainWindow.ChangeAddress2),
new CoerceValueCallback(MainWindow.CoerceAddress)));
Typically, only the 'DpDefault' attribute would be used, but even if it doesn't make the code shorter, it certainly makes it clearer. Here would be a more typical example:
Before:
[DpDefault("The Void")]
public string Address { get; set; }
After:
public string Address {
get { return (string)GetValue(AddressProperty); }
set { SetValue(AddressProperty, value); }
}
public static readonly DependencyProperty AddressProperty =
DependencyProperty.Register("Address", typeof(string), typeof(MainWindow),
new UIPropertyMetadata((string)"The Void"));
"Magic" is almost always a terrible name for method or property or variable in any language. You should rename the attribute to something more descriptive. Imagine you are just a random internet pedestrian and stumble on a piece code with attribute "Magic", what does it tell you about the code? Exactly nothing :)
I will try your code anyways, it has potential to be quite a timesaver. This should definitely be a part of .NET.
Something that might make your life a little easier is this... (Ive picked it up from Caliburn Micro).
public virtual void NotifyOfPropertyChange<TProperty>(Expression<Func<TProperty>> property) {
NotifyOfPropertyChange(property.GetMemberInfo().Name);
}
This enables you to do the following..
NotifyOfProperyChange(() =>
this.PropertyName);
This will highlight any issues with the code at design time, rather than run time.
Caliburn Micro is an awesome little framework that you should take a look at, it removes so much of the wiring up involved with MVVM and Silverlight / WPF!
This can already be done using a AOP (Aspect Oriented Programming) tool like PostSharp : http://www.richard-banks.org/2009/02/aspect-oriented-programming.html (using v1.x)
http://www.sharpcrafters.com/solutions/ui#data-binding (using v2.0)
I used PostSharp to implement INPC in few projects and it worked out pretty well, the code is much more cleaner and maintainable (it adds a few seconds to compile time)

MVVM - RaisePropertyChanged turning code into a mess

New to MVVM so please excuse my ignorance.
I THINK i'm using it right but I find my ViewModel has too many of these:
RaisePropertyChanged("SomeProperty")
Every time I set a property I have to raise that damned property changed.
I miss the days where I could just go:
public int SomeInteger { get; private set;}
These days I have to stick the "RaisePropertyChanged" in everywhere or my UI does not reflect the changes :(
Am I doing it wrong or are other people getting annoyed with the excessive number of magic strings and old school property setters?
Should I be using dependency properties instead? (I doubt that would help the code bloat anyway)
Despite these problems I still think MVVM is the way to go so I guess that's something.
Take a look at this What is the best or most interesting use of Extension Methods you've seen?.
It describes an extension method and a helper method that my Model and ViewModel classes use to enable the following strongly typed (no magic string) properties.
private string _name;
public string Name
{
get { return _name; }
set { this.NotifySetProperty(ref _name, value, () => this.Name); }
}
This is about as simple as I think it can get. Hope it helps.
You could use PostSharp's NotifyPropertyChanged attribute. Then all you have to do is to put an attribute on the class and that's it. E.g.:
[NotifyPropertyChanged]
public class MyClass
{
public string MyProperty { get; set; }
}
It helps to look at things from a different perspective: those are not complicated .NET properties, but simplified dependency properties.
Bindable properties of a view model in WPF are not identical to .NET properties, instead it is a kind of key-value store. If you want light-weight alternative to DependencyObject, you have an ability to implement this key-value store just buy calling certain function in setters - not bad, actually. Far from ideal too, of course, but your point of view is certainly unfair.
It does not get you back to the clean code, but I use a simple extension method to get the property name to avoid problems with magic strings. It also maintains the readability of the code, i.e. it is explicit what is happening.
The extension method is simply as follows:
public static string GetPropertyName(this MethodBase methodBase)
{
return methodBase.Name.Substring(4);
}
With this it means that you property sets are resilient against name changes and look like the following:
private string _name;
public string Name
{
get { return _name; }
set
{
name = value;
RaisePropertyChanged(MethodBase.GetCurrentMethod().GetPropertyName());
}
}
I've written more about this extension method here and I've published a matching code snippet here.
This will help:
"Kind Of Magic"
Effortless INotifyPropertyChanged
[http://visualstudiogallery.msdn.microsoft.com/d5cd6aa1-57a5-4aaa-a2be-969c6db7f88a][1]
as an example for adding it to one property:
[Magic]
public string Name { get { return _name; } set { _name = value; } }
string _name;
Another example for adding it to all the class properties:
[Magic]
public class MyViewModel: INotifyPropertyChanged
{
public string Name { get; set; }
public string LastName { get; set; }
.....
}

Resources