Quantcast
Channel: patterns & practices: Prism
Viewing all articles
Browse latest Browse all 1878

Commented Unassigned: ExtractPropertyName can be used only for properties in current class [10306]

$
0
0
PropertySuport.ExtractPropertyName is not supported when you want to extract property:
a, from other class then the caller's class
b, from static method/constructor

```
public class ClassA
{
public string Property1 { get; set; }
}

public class ClassB
{
public string Property2 { get; set; }

public string GetClassBPropertyName()
{
return PropertySupport.ExtractPropertyName(() => Property2)
}

public string GetClassAPropertyName()
{
throw new NotImplementedException();
}
}
```

If you add new method to PropertySupprt:

```
public static string ExtractPropertyName<TPropertyType, TClassType>(Expression<Func<TClassType, TClassType, TPropertyType>> propertyExpression)
{
if (propertyExpression == null)
{
throw new ArgumentNullException("propertyExpression");
}

var memberExpression = propertyExpression.Body as MemberExpression;
if (memberExpression == null)
{
throw new ArgumentException("The expression is not a member access expression.", "propertyExpression");
}

var property = memberExpression.Member as PropertyInfo;
if (property == null)
{
throw new ArgumentException("The member access expression does not access a property.", "propertyExpression");
}

var getMethod = property.GetGetMethod(true);
if (getMethod.IsStatic)
{
throw new ArgumentException("The referenced property is a static property.", "propertyExpression");
}

return memberExpression.Member.Name;
}
```
then it could be used like this:
```
public string GetClassAPropertyName()
{
PropertySupport.ExtractPropertyName<string, ClassA>((x, y) => x.Property2)
}

```
Comments: ** Comment from web user: spudcz **

Hi,

I used this in my project where I needed to listen to notifications in other class. there are other solutions when you can create:
1, custom events
2, attach to NotifyPropertyChanged event a check e.PropertyName = "NameOfProperty".

First case unnecessarily fills code with lots of single-purpose events and the second one is ugly because you need to specify changed property by it's string name. Why not to use existing NotifyPropertychanged event and handle it's callbacks more elegant.

So I added the overload method into PropertySupport and I can handlle NotifyPropertychanged event wherever I want.

See my sample scenario - you have viemodel with collection of Items that contain informatoin about it's sorting state (direction and sorting index). When you set any item as sorted/unsorted or change it's sorting index, you need to catch this event and reindex other items in collection.

```
public class SortableItem : NotificationObject
{
private ListSortDirection? _direction;
private int _sortIndex;

public ListSortDirection? Direction
{
get { return _direction; }
set { _direction = value; RaisePropertyChanged(() => Direction); }
}
public int SortIndex
{
get { return _sortIndex; }
set { _sortIndex = value; RaisePropertyChanged(() => SortIndex); }
}
}

public class SortableItemsViewModel : BaseViewModel
{
private static readonly string SortDirectionPropertyName;
private static readonly string SortSequenceNoPropertyName;
private readonly ObservableCollection<SortableItem> _items;

static SortableItemsProvider()
{
SortDirectionPropertyName = PropertySupport.ExtractPropertyName<ListSortDirection?, SortableItem>((x, y) => x.Direction);
SortSequenceNoPropertyName = PropertySupport.ExtractPropertyName<int, SortableItem>((x, y) => y.SortIndex);
}

public SortableItemsViewModel()
{
_items = new ObservableCollection<SortableItem>();
_items.CollectionChanged += OnItemsCollectionchanged;
}

public ObservableCollection<SortableItem> Items
{
get { return _items; }
}

private void OnItemsCollectionchanged(object sender, NotifyCollectionChangedEventArgs e)
{
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
foreach (SortableItem newItem in e.NewItems) {
newItem.PropertyChanged += OnSortableItemPropertyChanged;
}
bread;
case NotifyCollectionChangedAction.Remove:
foreach (SortableItem oldItem in e.OldItems) {
oldItem.PropertyChanged -= OnSortableItemPropertyChanged;
}
bread;
// TODO
}
}

private void OnSortableItemPropertyChanged(object sender, PropertyChangedEventArgs e)
{
var changedItem = (SortableItem)sender;

if (e.PropertyName == SortDirectionPropertyName) {
GenerateSortIndexes();
}
else if (e.PropertyName == SortSequenceNoPropertyName) {
Reindex(changedItem);
}
}

private void GenerateSortIndexes()
{
// TODO
}

private void Reindex(SortableItem changedItem)
{
// TODO
}

}
```


Viewing all articles
Browse latest Browse all 1878

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>