I need to add UnitCost to the Add Invoice Details Selector screen that appears when Add Invoice is clicked in Sales Order screen when the invoice type is a credit or return. I am new to Acumatica and not sure how I need to do it as an extension. I added it to InvoiceSplits but when I put breakpoints in there, I never hit them.
I added this code to SOOrderEntry...am I on the right track?
namespace PX.Objects.SO
{
public class SOOrderEntry_Extension : PXGraphExtension<SOOrderEntry>
{
[System.SerializableAttribute()]
public class InvoiceSplits : IBqlTable
{
#region UnitCost
public abstract class unitCost : PX.Data.IBqlField
{
}
protected Decimal? _UnitCost;
[PXDBPriceCost()]
[PXUIField(DisplayName = "Unit Cost")]
public virtual Decimal? UnitCost
{
get
{
return this._UnitCost;
}
set
{
this._UnitCost = value;
}
}
}
#endregion
#region Event Handlers
public delegate InvoiceSplits CreateInvoiceSplitsDelegate(ARTran artran, SOLine line, SOSalesPerTran sptran, INTran tran, INTranSplit split);
// [PXOverride]
public InvoiceSplits CreateInvoiceSplits(ARTran artran, SOLine line, SOSalesPerTran sptran, INTran tran, INTranSplit split, CreateInvoiceSplitsDelegate baseMethod)
{
InvoiceSplits invSplit = new InvoiceSplits();
invSplit.UnitCost = artran.UnitCost;
if (tran != null)
{
invSplit.UnitCost = split.UnitCost ?? tran.UnitCost;
}
return invSplit;
// return baseMethod(artran,line,sptran,tran,split);
}
Instead of creating a separate InvoiceSplits class, you would want to make a PXCacheExtension of InvoiceSplits.
public sealed class InvoiceSplitsExtension : PXCacheExtension<InvoiceSplits>
{
#region UnitCost
public abstract class unitCost : IBqlField
{
}
[PXDBPriceCost]
[PXUIField(DisplayName = "Unit Cost")]
public decimal? UnitCost { get; set; }
#endregion
}
Then in the PXOverride of the CreateInvoiceSplits method you would get the CacheExtension and set the UnitCost on that.
public delegate InvoiceSplits CreateInvoiceSplitsDel(ARTran artran, SOLine line, SOSalesPerTran sptran, INTran tran, INTranSplit split);
[PXOverride]
public InvoiceSplits CreateInvoiceSplits(ARTran artran, SOLine line, SOSalesPerTran sptran, INTran tran, INTranSplit split, CreateInvoiceSplitsDel del)
{
InvoiceSplits invSplit = del?.Invoke(artran, line, sptran, tran, split);
InvoiceSplitsExtension invSplitExt = PXCache<InvoiceSplits>.GetExtension<InvoiceSplitsExtension>(invSplit);
invSplitExt.UnitCost = artran.UnitCost;
if (tran != null)
{
invSplitExt.UnitCost = split.UnitCost ?? tran.UnitCost;
}
return invSplit;
}
Lastly, you will need to add your UnitCost field to the UI. To do this you will need to go into a customization package, customize the SO301000 screen and navigate to Dialogs->Dialog: Add Invoice Details->Grid: invoiceSplits on the tree view. Then go to the "Add Data Fields" tab, select your UnitCost field and click create controls.
Related
I'm having trouble getting my fields to load when a value is selected from a selector. First screen (Group-Categories) has a Group Selector that displays description in textfield and grid where users can input Categories and Cat Descriptions. This works perfectly.
// Group DAC
[Serializable]
public class INMerchandiseGroup : IBqlTable
{
#region GroupCD
[PXDBString(10, IsKey = true, BqlField = typeof(INMerchandiseGroup.groupCD))]
[PXUIField(DisplayName = "Group Code", Visibility=PXUIVisibility.SelectorVisible)]
[PXSelector(typeof(Search<INMerchandiseGroup.groupCD>),
typeof(INMerchandiseGroup.groupCD),
typeof(INMerchandiseGroup.description))]
public virtual string GroupCD { get; set; }
public abstract class groupCD : PX.Data.BQL.BqlString.Field<groupCD> { }
#endregion
#region Description
[PXDBString(256, IsUnicode = true, BqlField = typeof(INMerchandiseGroup.description))]
[PXUIField(DisplayName = "Description")]
public virtual string Description { get; set; }
public abstract class description : PX.Data.BQL.BqlString.Field<description> { }
#endregion
}
// Group Graph
public class BPGroupCategoryMaint : PXGraph<BPGroupCategoryMaint, INMerchandiseGroup>
{
// Setup for GroupCd in grid
#region Category GroupCD
[PXMergeAttributes(Method = MergeMethod.Append)]
[PXDBDefault(typeof(INMerchandiseGroup.groupCD))]
protected virtual void INMerchandiseCategory_GroupCD_CacheAttached(PXCache cache)
{
}
#endregion
public PXSelect<INMerchandiseGroup> CurrentGroup;
public PXSave<INMerchandiseGroup> Save;
public PXCancel<INMerchandiseGroup> Cancel;
public PXSelect<INMerchandiseCategory,
Where<INMerchandiseCategory.groupCD, Equal<Current<INMerchandiseGroup.groupCD>>>>
GroupCategories;
}
I have same setup in Category-Dept screen. User selects Category from selector and the Cat Description and Group CD should populate text boxes, but category description and groupcd only populate the first time. After that, the values in cache are null. What am I doing incorrectly?
// Category DAC (this is used in the grid of Group screen, and as a record header in Category screen.
[Serializable]
public class INMerchandiseCategory : IBqlTable
{
#region CategoryCD
[PXDBString(10, IsKey = true, BqlField = typeof(INMerchandiseCategory.categoryCD, InputMask = ">CCCCCCCCCC")]
[PXUIField(DisplayName = "Category Code")]
public virtual string CategoryCD { get; set; }
public abstract class categoryCD : PX.Data.BQL.BqlString.Field<categoryCD> { }
#endregion
#region Description
[PXDBString(256, IsUnicode = true, BqlField = typeof(INMerchandiseCategory.categoryDescription))]
[PXUIField(DisplayName = "Category Description")]
public virtual string CategoryDescription { get; set; }
public abstract class categoryDescription : PX.Data.BQL.BqlString.Field<categoryDescription> { }
#endregion
#region GroupCD
[PXDBString(10, IsKey = true, BqlField = typeof(INMerchandiseCategory.groupCD) )]
[PXUIField(DisplayName = "Group Code")]
public virtual string GroupCD { get; set; }
public abstract class groupCD : PX.Data.BQL.BqlString.Field<groupCD> { }
#endregion
}
// Category Graph
public class BPCategoryDeptMaint : PXGraph<BPCategoryDeptMaint>
{
[PXMergeAttributes(Method = MergeMethod.Merge)]
[PXUIField(DisplayName = "Category Code", Visibility=PXUIVisibility.SelectorVisible)]
[PXSelector(typeof(Search2<INMerchandiseCategory.categoryCD,
InnerJoin<INMerchandiseGroup, On<INMerchandiseCategory.groupCD, Equal<INMerchandiseGroup.groupCD>>>>),
typeof(INMerchandiseCategory.categoryCD),
typeof(INMerchandiseCategory.categoryDescription),
typeof(INMerchandiseCategory.groupCD),
typeof(INMerchandiseGroup.description))]
protected virtual void INMerchandiseCategory_CategoryCD_CacheAttached(PXCache cache)
{
}
#region Dept GroupCD
[PXMergeAttributes(Method = MergeMethod.Append)]
[PXDefault(typeof(INMerchandiseCategory.groupCD), PersistingCheck = PXPersistingCheck.Nothing)]
protected virtual void INMerchandiseDept_GroupCD_CacheAttached(PXCache cache)
{
}
#endregion
#region Dept CategoryCD
[PXMergeAttributes(Method = MergeMethod.Append)]
[PXDefault(typeof(INMerchandiseCategory.categoryCD), PersistingCheck = PXPersistingCheck.Nothing)]
protected virtual void INMerchandiseDept_CategoryCD_CacheAttached(PXCache cache)
{
}
#endregion
public PXSelect<INMerchandiseCategory> CurrentCategory;
public PXSave<INMerchandiseCategory> Save;
public PXCancel<INMerchandiseCategory> Cancel;
public PXSelect<INMerchandiseDept,
Where<INMerchandiseDept.groupCD, Equal<Current<INMerchandiseCategory.groupCD>>,
And<INMerchandiseDept.categoryCD, Equal<Current<INMerchandiseCategory.categoryCD>>>>>
CategoryDepts;
}
}
Make sure the field in the ASPX has attribute commit=true. If flagged for commit, then the UI will send the update to the server when the control is changed.
There is a custom field, that I declared for the Customer DAC:
public class CustomerExt : PXCacheExtension<Customer>
{
#region UsrDemoField
[PXDBString(255)]
[PXUIField(DisplayName = "Demo Field")]
public virtual string UsrDemoField { get; set; }
public abstract class usrDemoField : IBqlField { }
#endregion
}
Attempts to modify the ARInvoice Customer selector with the Customize Selector Columns popup didn't seem to work. How can I add my custom field into the ARInvoice customer selector?
Be aware, since Acumatica ERP build #17.201.0043, it's possible to customize the list of columns defined for AR Invoices' Customer lookup via the Customize Selector Columns dialog (available in the Data Class section of the Customization Manager). For step-by-step instructions please check the screenshot below:
To modify AR Invoices' Customer lookup on Acumatica ERP ver. 6.1 and earlier, please follow the steps below:
The definition of PXCustomizeSelectorColumns generated by the Customize Selector Columns popup brilliantly works with the majority of selectors inside Acumatica ERP. Basically, PXCustomizeSelectorColumns simply replaces originally defined columns for a selector with the custom set of columns during an initialization of PXCache:
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Method, AllowMultiple = false)]
public class PXCustomizeSelectorColumns: PXEventSubscriberAttribute
{
private readonly Type[] _columns;
public PXCustomizeSelectorColumns(params Type[] columns)
{
_columns = columns;
}
public override void CacheAttached(PXCache cache)
{
cache.SetAltered(this.FieldName, true);
foreach (PXEventSubscriberAttribute attr in cache.GetAttributes(null, this.FieldName))
{
PXSelectorAttribute sel = attr as PXSelectorAttribute;
if (sel == null)
continue;
sel.SetFieldList(_columns);
sel.Headers = null;
}
}
}
So what can cause the PXCustomizeSelectorColumns attribute to fail and not replace selector's originally defined columns? Any time the SetColumns method is executed on an instance of PXDimensionSelectorAttribute or PXSelectorAttribute after PXCache was initialized, there is no chance for PXCustomizeSelectorColumns to do its job.
[PXDBInt()]
[PXUIField(DisplayName = "Customer", Visibility = PXUIVisibility.Visible)]
[Serializable]
public class CustomerAttribute : AcctSubAttribute
{
...
public virtual void FieldSelecting(PXCache sender, PXFieldSelectingEventArgs e)
{
if (this.AttributeLevel == PXAttributeLevel.Item || e.IsAltered)
{
PopulateFields(sender);
}
PXFieldSelecting handler = GetAttribute<PXDimensionSelectorAttribute>().FieldSelecting;
handler(sender, e);
}
protected virtual void PopulateFields(PXCache sender)
{
if (_FieldList == null)
{
_FieldList = new string[this._fields.Length];
_HeaderList = new string[this._fields.Length];
for (int i = 0; i < this._fields.Length; i++)
{
Type cacheType = BqlCommand.GetItemType(_fields[i]);
PXCache cache = sender.Graph.Caches[cacheType];
if (cacheType.IsAssignableFrom(typeof(BAccountR)) ||
_fields[i].Name == typeof(BAccountR.acctCD).Name ||
_fields[i].Name == typeof(BAccountR.acctName).Name)
{
_FieldList[i] = _fields[i].Name;
}
else
{
_FieldList[i] = cacheType.Name + "__" + _fields[i].Name;
}
_HeaderList[i] = PXUIFieldAttribute.GetDisplayName(cache, _fields[i].Name);
}
}
var attr = GetAttribute<PXDimensionSelectorAttribute>().GetAttribute<PXSelectorAttribute>();
attr.SetColumns(_FieldList, _HeaderList);
}
...
}
With that said, to add a custom field into the ARInvoice Customer selector, one should replace all attributes declared for the ARInvoice.CustomerID field and redefine columns for the Customer selector within the CustomerActive attribute:
[PXDefault()]
[CustomerActive(typeof(Search<BAccountR.bAccountID>),
new Type[]
{
typeof(BAccountR.acctCD),
typeof(BAccountR.acctName),
typeof(CustomerExt.usrDemoField),
typeof(Address.addressLine1),
typeof(Address.addressLine2),
typeof(Address.postalCode),
typeof(CustomerAttribute.Contact.phone1),
typeof(Address.city),
typeof(Address.countryID),
typeof(CustomerAttribute.Location.taxRegistrationID),
typeof(Customer.curyID),
typeof(CustomerAttribute.Contact.salutation),
typeof(Customer.customerClassID),
typeof(Customer.status)
},
Visibility = PXUIVisibility.SelectorVisible, DescriptionField = typeof(Customer.acctName), Filterable = true, TabOrder = 2)]
After publishing the customization, custom Demo Field should finally appear in the ARInvoice Customer selector:
To enable searching against a custom field inside the ARInvoice Customer selector, open Invoices and Memos screen in the Layout Editor and type UsrDemoField as the GridProperties.FastFilterFields property of the Customer selector:
I have created a bunch of custom templates to store items (such as Industries, Subindustries, etc.) in Sitecore. I now want to go about loading these into my Sitecore MVC model.
The lists are located in sitecore > Content > Lists. For example inside the Lists folder there is a folder called Country. I want to get back all the items within the Country folder and populate them as unordered list in my view.
UPDATE: I implemented the Glass.Mapper.Sc method suggested below. It is fully operational now.
This is what my working model looks like now:
using Glass.Mapper.Sc.Configuration;
using Glass.Mapper.Sc.Configuration.Attributes;
using Sitecore.Data.Items;
using Sitecore.Mvc.Presentation;
using System;
using System.Collections.Generic;
namespace Sitecore.Web.Models
{
public class Registration: IRenderingModel
{
public Rendering Rendering { get; set; }
public Item Item { get; set; }
public Item PageItem { get; set; }
public IEnumerable<CountryChildItem> CountryList { get; set; }
[SitecoreType(AutoMap = true)]
public class CountryItem
{
public virtual IEnumerable<CountryChildItem> Children { get; set; }
}
[SitecoreType(AutoMap = true)]
public class CountryChildItem
{
[SitecoreId]
public virtual Guid Id { get; set; }
[SitecoreInfo(SitecoreInfoType.Path)]
public virtual string Path { get; set; }
[SitecoreField]
public virtual string DisplayName { get; set; }
[SitecoreField]
public virtual string Abbreviation { get; set; }
}
public void Initialize(Rendering rendering)
{
Rendering = rendering;
Item = rendering.Item;
PageItem = PageContext.Current.Item;
}
}
}
and this is what my working contoller looks like:
using Glass.Mapper.Sc;
using Sitecore.Web.Models;
using System.Web.Mvc;
namespace Sitecore.Web.Controllers
{
public class RegistrationController : Controller
{
Registration registrationModel = new Registration();
public ActionResult Index()
{
ISitecoreContext sitecoreContext = new SitecoreContext();
ISitecoreService service = new SitecoreService(sitecoreContext.Database);
Registration.CountryItem countryItem = service.GetItem<Registration.CountryItem>("/sitecore/content/Lists/Country");
registrationModel.CountryList = countryItem.Children;
return View(registrationModel);
}
}
}
and a snippet of my working view:
<ul class="select-menu-options dropdown-menu">
#foreach (var country in Model.CountryList)
{
<li>#country.DisplayName</li>
}
</ul>
If I were in your position I'd look into Glassmapper for Sitecore.
It's a fairly lightweight ORM for Sitecore.
http://www.glass.lu/Mapper/Sc
I'd also suggest moving the lists located in
sitecore > Templates > User Defined > Lists > Content
to some where under either
sitecore > Content
or
sitecore > System
(whichever makes more sence)
UPDATE:
Try adding this above your class:
[SitecoreType(AutoMap = true)]
public class CountryItem
{
//...
}
If you change your CountryItem and other model classes to inherit from SearchResultItem like that:
[PredefinedQuery("TemplateID", ComparisonType.Equal, "{ID-OF-CountryItem-TEMPLATE}", typeof(ID))]
public class CountryItem : Sitecore.ContentSearch.SearchTypes.SearchResultItem
{
[IndexField("_displayname")]
public virtual string DisplayName { get; set; }
[IndexField("abbreviation")]
public string Abbreviation { get; set; }
}
You should be able to use Sitecore indexes to retrieve all the countries and other lists like that:
private static string IndexName
{
get
{
return string.Format("sitecore_{0}_index", (Context.ContentDatabase ?? Context.Database).Name);
}
}
private static string Language { get { return Context.Language.Name; } }
public IEnumerable<CountryItem> GetCountries()
{
using (var context = ContentSearchManager.GetIndex(IndexName).CreateSearchContext())
{
IQueryable<CountryItem> queryable = context.GetQueryable<CountryItem>();
queryable = queryable.Where(i => i.Language == Language);
queryable = queryable.Where(i => i.LatestVersion);
// ... maybe excluding standard values or some other filters
var searchResults = queryable.GetResults();
return queryable.ToList();
}
}
Please be aware that this is just an example. You need to test it and most probably adapt to your solution.
And as Dar Brett mentioned, you should not keep any data items under the Templates node.
I have a requirement in which I'm implementing sitecore WFFM to create a form. The page has HTML input tags with Placeholder attribute. I have to render the WFFM SingleLineInput box to a input tag with placeholder attribute. What should I do?
I know that the SingleLineText class is define in the Sitecore.Form.Web.UI.Controls dll.
If you are using MVC version of WFFM you need to add following as explained in approved answer
1- Create a class
public interface IPlaceholderField
{
string PlaceHolder { get; set; }
}
[ValidationProperty("Text")]
public class SingleLineText : Sitecore.Form.Web.UI.Controls.SingleLineText, IPlaceholderField
{
[VisualCategory("Custom Properties")]
[VisualProperty("Placeholder", 2)]
[DefaultValue("")]
public string PlaceHolder { get; set; }
protected override void OnInit(EventArgs e)
{
// Set placeholder text, if present
if (!string.IsNullOrEmpty(PlaceHolder))
{
textbox.Attributes["placeholder"] = PlaceHolder;
}
base.OnInit(e);
}
}
public class ExtendedSingleLineTextField : Sitecore.Forms.Mvc.ViewModels.Fields.SingleLineTextField, IPlaceholderField
{
[VisualCategory("Custom Properties")]
[VisualProperty("Placeholder", 2)]
[DefaultValue("")]
public string PlaceHolder { get; set; }
}
2- Copy Single-Line Text from /sitecore/system/Modules/Web Forms for Marketers/Settings/Field Types/Simple Types/Single-Line Text to /sitecore/system/Modules/Web Forms for Marketers/Settings/Field Types/Custom
set Assembly,Class and MVC Type
3-Create a new chtml file under \Views\Form\EditorTemplates ane name it ExtendedSingleLineTextField.cshtml it should be same name with the class name(ExtendedSingleLineTextField)
#using Sitecore.Forms.Mvc.Html
#using LendLease.Web.HtmlHelpers
#model LendLease.Extension.Sc.WFFM.ExtendedSingleLineTextField
#using (Html.BeginField())
{
#*#Html.TextBoxFor(m => m.Value, new { placeholder = Model.PlaceHolder })*#
#Html.ExtendedBootstrapEditor("value",Model.PlaceHolder,"",new []{""})
}
add a html helper so you can inject placeholder i named it BootstrapEditorHtmlHelperExtension.cs
public static class BootstrapEditorHtmlHelperExtension
{
public static MvcHtmlString ExtendedBootstrapEditor(this HtmlHelper helper, string expression, string placeholderText, string inlineStyle, string[] classes)
{
var str = string.Empty;
var viewModel = helper.ViewData.Model as IViewModel;
if (viewModel != null)
{
var styleSettings = viewModel as IStyleSettings;
if (styleSettings != null)
{
str = styleSettings.CssClass;
}
if (string.IsNullOrEmpty(placeholderText))
{
placeholderText = viewModel.Title;
}
}
return helper.Editor(expression, new
{
htmlAttributes = new
{
#class = (string.Join(" ", classes) + " form-control" + (string.IsNullOrEmpty(str) ? string.Empty : " " + str) + (helper.ViewData.Model is SingleLineTextField ? " dangerousSymbolsCheck" : string.Empty)),
placeholder = placeholderText,
style = (inlineStyle ?? string.Empty)
}
});
}
}
You can achieve this by extending SingleLineText with an additional property to store the placeholder's text value. Once the property is in place, you'll need to override the OnInit method and inject the placeholder attribute if one happens to be set.
public interface IPlaceholderField
{
string PlaceholderText { get; set; }
}
Here is the custom implementation of SingleLineText
[ValidationProperty("Text")]
public class SingleLineText : Sitecore.Form.Web.UI.Controls.SingleLineText, IPlaceholderField
{
[VisualCategory("Custom Properties")]
[VisualProperty("Placeholder Text", 2)]
[DefaultValue("")]
public string PlaceholderText { get; set; }
protected override void OnInit(EventArgs e)
{
// Set placeholder text, if present
if (!String.IsNullOrEmpty(PlaceholderText))
{
textbox.Attributes["placeholder"] = PlaceholderText;
}
base.OnInit(e);
}
}
Finally, you will need to create a new field item definition under /sitecore/system/Modules/Web Forms for Marketers/Settings/Field Types/Custom/ and set the assembly to use the class above. Your new placeholder property should appear under a "Custom Properties" category when you have the field selected in the Form Designer.
I used the following code to create a Custom Field. And It works fine :)
internal class CustomType : SingleLineText
{
[VisualProperty("Placeholder", 100)]
[VisualCategory("Appearance")]
public string placeholderText
{
get;
set;
}
protected override void DoRender(System.Web.UI.HtmlTextWriter writer)
{
this.textbox.Attributes.Add("placeholder", this.PlaceholderText );
base.DoRender(writer);
}
}
Then i just created an Field Type Item under /sitecore/system/Modules/Web Forms for Marketers/Settings/Field Types/Custom and entered assembly and class details in the item.
Works like a charm...!!
I posted this question on the Silverlight forums, but haven't been able to get an answer to solve my issue, so I hope the guru's at SO can help!
Basically I have an entity property in my parent viewmodel. When this entity changes I need the ID of the entity in my child viewmodel. I have created a child control with a dependency property and created a binding in the constructor. I am trying to implement all this using MVVM and MEF.
My ParentViewModel:
[ExportPlugin(ViewModelTypes.ParentViewModel, PluginType.ViewModel)]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class ParentViewModel: ViewModelBase
{
private Person _currentPerson;
public Person CurrentPerson
{
get { return _currentPerson; }
private set
{
if (!ReferenceEquals(_currentPerson, value))
{
_currentPerson= value;
RaisePropertyChanged("CurrentPerson");
}
}
}
}
My ParentUserControl:
<UserControl x:Class="MyApp.ParentUserControl" x:Name="ParentControl">
<local:ChildUserControl PersonID="{Binding ElementName=ParentControl, Mode=TwoWay, Path=DataContext.CurrentPerson.ID}" />
</UserControl>
My ChildUserControl codebehind:
public partial class ChildUserControl : UserControl
{
#region Private Properties
private PluginCatalogService _catalogService = PluginCatalogService.Instance;
#endregion
#region Dependency Properties
public static readonly DependencyProperty PersonIDProperty =
DependencyProperty.Register("PersonID", typeof(int), typeof(ChildUserControl), new PropertyMetadata(OnPersonIDChanged));
#endregion
#region Public Properties
public int PersonID
{
get { return (int)GetValue(PersonIDProperty); }
set { SetValue(PersonIDProperty, value); }
}
#endregion
#region Constructor
public ChildUserControl()
{
InitializeComponent();
if (!ViewModelBase.IsInDesignModeStatic)
this.DataContext = _catalogService.FindPlugin(ViewModelTypes.ChildViewModel, PluginType.ViewModel);
this.SetBinding(PersonIDProperty, new Binding("PersonID") { Mode = BindingMode.TwoWay, Source = DataContext, UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged });
}
#endregion
private static void OnPersonIDChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
...
}
My ChildViewModel:
[ExportPlugin(ViewModelTypes.ChildViewModel, PluginType.ViewModel)]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class ChildViewModel: ViewModelBase
{
private int _personID;
public int PersonID
{
get { return _personID; }
set
{
if (!ReferenceEquals(_personID, value))
{
_personID= value;
RaisePropertyChanged("PersonID");
}
}
}
}
I created the OnPersonIDChanged event to see if when the CurrentPerson entity changed, the change was being picked up in the ChildControl, which it is. It just isn't being picked up in the ChildControl ViewModel.
Any help is much appreciated.
Preferably, if you are using PRISM you can use the EventAggregator...
see http://msdn.microsoft.com/en-us/library/ff921122(v=pandp.40).aspx and https://compositewpf.codeplex.com/
Another option would be to hook (hack) onto the PropertyChanged
ViewModel1.PropertyChanged += (s, e) =>
{
if (e.PropertyName == "XXX")
{
ViewModel2.PropertyX = vm1.PropertY;
}
};