I view link demo of openxava.http://demo.sicflex.com/group/empresas-abc/inventory-items.
- I enter to Inventory Management->Item.when i choose "Inventory Group" then "Inv.Sub Group " will have list of Inventory Group. Help me. Thank All.
You should use a #SearchAction in the inventory group reference.
You can annotate the reference in this way:
#ManyToOne(fetch=FetchType.LAZY) #SearchAction("MyReference.search")
private Seller seller;
Then you define the action in controllers.xml, thus:
<controller name="MyReference">
<action name="search" hidden="true"
class="org.openxava.test.actions.MySearchAction"
image="images/search.gif">
</action>
</controller>
Finally, you have to write your own search action where you can define your own filter:
public class MySearchAction extends ReferenceSearchAction {
public void execute() throws Exception {
super.execute(); // The standard search behaviour
getTab().setBaseCondition("${number} < 3"); // Adding a filter to the list
}
}
Related
I am trying to add a dialog box to the SO301000 screen, this dialog box (I think its also considered a smart panel but the difference is lost on me) is just supposed to show a list of orders that a customer has made.
What I have working:
1: I am able to pull all of the orders that a customer has made.
2: I am able to open/close the dialog box after clicking the action.
3: An order IS able to be put into grid.
What doesn't work:
1: I am unable to get more than one order into the grid.
I have no need to edit the orders in this grid, I just want to puke out quick information.
public class SOOrderEntry_Extension : PXGraphExtension<SOOrderEntry>
{
public PXFilter<MSCustomerOrderDac> MSCustomerViewForm;
public PXFilter<MSCustomerOrderDac> MSCustomerOrderViews; //Issue.
public PXAction<SOOrder> ViewCustomerOrders;
[PXUIField(DisplayName = "View Custoemr", MapEnableRights = PXCacheRights.Select, MapViewRights = PXCacheRights.Select)]
[PXButton(Category = "Other")]
[PXUIEnabled(typeof(Where<SOOrder.customerID.IsNotNull>))]
protected virtual IEnumerable viewCustomerOrders(PXAdapter adapter)
{
MSCustomerOrderViews.AllowInsert=true;
PXSelectBase<SOOrder> orders =
new PXSelectReadonly<SOOrder,
Where<SOOrder.customerID, Equal<Current<SOOrder.customerID>>>>(Base);
int linenumber = 0;
foreach (SOOrder order in orders.Select())
{
MSCustomerOrderDac newOrder = new MSCustomerOrderDac();
newOrder.OrderNumber = order.OrderNbr;
newOrder.LineNbr = linenumber++;
newOrder = MSCustomerOrderViews.Insert(newOrder);
}
if (MSCustomerViewForm.AskExt(true) != WebDialogResult.OK) //need this to show the form
{}
return adapter.Get();
}
[PXVirtual]
[Serializable]
public class MSCustomerOrderDac : IBqlTable
{
#region OrderNumber
[PXString]
[PXUIField(DisplayName = "Order Number")]
public virtual String OrderNumber { get; set; }
public abstract class orderNumber : PX.Data.BQL.BqlString.Field<orderNumber> { }
#endregion
[PXInt(IsKey = true)]
public virtual Int32? LineNbr { get; set; }
public abstract class lineNbr : PX.Data.BQL.BqlInt.Field<lineNbr> { }
}
}
This is the whole of my code, I also tried breaking the loop and adding more than 1 items manually but that made no difference.
I also found this thread on the community forums: https://community.acumatica.com/customizations-187/dialog-with-grid-with-in-memory-dac-from-action-button-8578
However I think he and I were having different issues.
Also, I have just noticed that the order that it is pushing is aways the same one.
The following code snippits will give you the desired functionality.
Create a graph extension that has an declared data view that will retrieve the information desired, in this case SOOrders related to the Customer.
public class SOOrderEntryExtension : PXGraphExtension<SOOrderEntry>
{
public PXSelectReadonly<SOOrder2, Where<SOOrder2.customerID, Equal<Current<SOOrder.customerID>>>> RelatedOrders;
public PXAction<SOOrder> ViewCustomerOrders;
[PXUIField(DisplayName = "View Customer Orders", MapEnableRights = PXCacheRights.Update, MapViewRights = PXCacheRights.Update)]
[PXButton]
protected virtual void viewCustomerOrders()
{
RelatedOrders.AskExt(true);
}
protected virtual void __(Events.RowSelected<SOOrder> e)
{
if(e.Row is SOOrder row)
{
ViewCustomerOrders.SetVisible(true);
ViewCustomerOrders.SetEnabled(true);
}
}
}
If multiple views are declared on a graph / extension that utilize the same DAC issues may occur. To overcome this issue a derived DAC needs to be created [SOOrder2] with the key / search criteria fields redeclared which will allow the framework to properly segregate the cache types.
[Serializable]
[PXHidden]
public class SOOrder2 : SOOrder
{
#region DocType
public new abstract class orderType : BqlString.Field<orderType>
{
}
#endregion
#region RefNbr
public new abstract class orderNbr : BqlString.Field<orderNbr>
{
}
#endregion
#region CustomerID
public new abstract class customerID : BqlInt.Field<customerID>
{
}
#endregion
}
The smart panel that your view utilizes can be found below :
<px:PXSmartPanel runat="server" ID="CustomerRelatedOrderPnl" Height="550px" Width="950px" CaptionVisible="True" Caption="Related Orders" Key="RelatedOrders" AutoCallBack-Target="CustomerRelatedOrderGrid" AutoCallBack-Command="Refresh">
<px:PXGrid runat="server" ID="CustomerRelatedOrderGrid" SyncPosition="True" Height="100%" SkinID="Inquire" Width="100%" DataSourceID="ds" NoteIndicator="False">
<AutoSize Enabled="True" />
<Levels>
<px:PXGridLevel DataMember="RelatedOrders">
<Columns>
<px:PXGridColumn DataField="OrderType" Width="140" />
<px:PXGridColumn DataField="OrderNbr" Width="140" />
<px:PXGridColumn DataField="CustomerID" Width="140" />
<px:PXGridColumn DataField="Status" Width="140" />
<px:PXGridColumn DataField="OrderDate" Width="140" />
<px:PXGridColumn DataField="CuryOrderTotal" Width="140" />
</Columns>
</px:PXGridLevel>
</Levels>
</px:PXGrid>
<px:PXPanel runat="server" ID="CustomerRelatedOrderButtonPnl">
<px:PXButton runat="server" DialogResult="OK" Text="Ok" CommandSourceID="ds" ID="CustomerRelatedOrderOK" />
</px:PXPanel>
</px:PXSmartPanel>
The results of this code can be seen here :
Not an answer, but I don't have enough reputation to comment.
Some extra information :
A PXFilter View can only have 1 instance of the DAC on the Graph.
You don't need to create a PXSelectBase instance unless you're going to be modifying the query based on conditions, or unless you're going to pass it somewhere else, such as into a PXFieldScope. You can simply do this (Using the proper separate DAC to prevent caching issues) :
foreach
(
SOOrder2 soOrder in PXSelectReadonly
<
SOOrder2,
Where
<
SOOrder2.customerID, Equal<Current<SOOrder.customerID>>
>
>.Select(Base)
)
{
...
}
By performing your Select and Insert inside the Action Delegate rather than having a View like in Josh's answer, or having a View Delegate, your logic will insert records every single time someone pushes the button, even if they already exist in the Cache.
You shouldn't need to check the result of AskExt.
I'm not 100% sure about this : If User A has SOOrderEntry open on an SOOrder and sits there for a bit, then User B creates a new SOOrder for the same Customer, if User A opens the popup, then it could be possible that Acumatica may not run the query again, and the new SOOrder may not pop up. If you experience this behavior, then you would have to Clear the View before calling AskExt. Acumatica should then run the query again, and the new SOOrder should appear.
Acumatica may try to persist your View, so you should put a PXVirtual Attribute on it, following the instructions in its summary tags.
You may want to add conditions to your query to exclude the current record from the results, unless it is your desire to include the current record in your popup.
Since #Joshua Van Hoesen gave such a detailed answer, I am going to post the solution I came to for completeness's sake and if anyone wants to see potentially another way to do it.
public class SOOrderEntry_Extension : PXGraphExtension<SOOrderEntry>
// It might be best practice to move these to their own file, but I think its better to keep it all together.
{
// This is just for the form so the cache for the grid doesnt get over written.
public PXFilter<MSCustomerOrderDac> MSCustomerViewForm;
// This is the for the grid, we have to use PXSelect because it is able to grab more than one item.
// Since our DAC is virtual we must mark it as such AND create a delagate.
[PXVirtualDAC]
public PXSelect<MSCustomerOrderDac> MSCustomerOrderViews;
// This delegate overrides the database call
// first letter in lower case (Your view has it Upper case sicne hte names must be the same)
public IEnumerable mSCustomerOrderViews()
{
// This just grabs the current view and ensures we dont go to the db, theoretically we could include anything.
return MSCustomerOrderViews.Cache.Cached;
}
// This is our action, were need the map rights so we can interact with things.
public PXAction<SOOrder> ViewCustomerOrders;
[PXUIField(DisplayName = "View Customer Order History", MapEnableRights = PXCacheRights.Select, MapViewRights = PXCacheRights.Select)]
[PXButton(Category = "Other",CommitChanges =true)]
[PXUIEnabled(typeof(Where<SOOrder.customerID.IsNotNull>))]
// This is the code that runs for the action that fills the grid.
protected virtual IEnumerable viewCustomerOrders(PXAdapter adapter)
{
PXSelectBase<SOOrder> orders =
new PXSelectReadonly<SOOrder,
Where<SOOrder.customerID, Equal<Current<SOOrder.customerID>>>>(Base);
int linenumber = 0;
foreach (SOOrder order in orders.Select())
{
linenumber++;
MSCustomerOrderViews.Current = MSCustomerOrderViews.Insert(new MSCustomerOrderDac() { LineNbr = linenumber });
var newOrder = MSCustomerOrderViews.Current;
newOrder.OrderNumber = order.OrderNbr;
MSCustomerOrderViews.Update(newOrder);
}
if (MSCustomerViewForm.AskExt(true) != WebDialogResult.OK) {} // This is how we get the form to show up, we want it after the loop so it is filled once it pops up.
return adapter.Get();
}
// This is our virtual DAC. When we create a Virtual DAC we HAVE to have a key column, in this case it is the line number.
[PXVirtual]
[Serializable]
[PXHidden]
public class MSCustomerOrderDac : IBqlTable
{
#region OrderNumber
[PXString]
[PXUIField(DisplayName = "Order Number")]
public virtual String OrderNumber { get; set; }
public abstract class orderNumber : PX.Data.BQL.BqlString.Field<orderNumber> { }
#endregion
#region LineNumber
[PXInt(IsKey = true)]
public virtual Int32? LineNbr { get; set; }
public abstract class lineNbr : PX.Data.BQL.BqlInt.Field<lineNbr> { }
#endregion
}
}
The comments are just for future me.
If anyone knows potential performance hits that could happen on mine please let me know!
I'm trying to setup a processing page that will update a SOShipment document lines with new data entered on the PXFilteredProcessing page. When declaring a PXString (virtual field), if I add the PXUIfield attribute, the field becomes read only.
Here is the DAC declaration showing the actual problem. The page I use is a simple PXFilteredProcessing page with a completely custom page that was made in Visual Studio.
#region StockRow
public abstract class stockRow : IBqlField { }
[PXString()]
[PXUIField(Enabled = true)]
public virtual String StockRow { get; set; }
#endregion
#region StockFlag
public abstract class stockFlag : IBqlField { }
[PXString]
public virtual String StockFlag { get; set; }
#endregion
The page has the fields defined as follow :
<px:PXTextEdit ID="edStockRow" runat="server"
DataField="StockRow" Enabled ="true" >
</px:PXTextEdit>
<px:PXTextEdit ID="edStockFlag" runat="server"
DataField="StockFlag" Enabled ="true">
</px:PXTextEdit>
<px:PXGridColumn DataField="StockRow" Width="200px" >
</px:PXGridColumn>
<px:PXGridColumn DataField="StockFlag" Width="200px">
</px:PXGridColumn>
Should the PXUIField really make the field become read only or is there something I am not getting?
PS: I know I can re-enable the field on the RowSelected even, I'm mostly looking for an explanation as to why this is happening.
if I add the PXUIfield attribute, the field becomes read only
Are you sure that this is the operation making the field read-only?
Typically all processing screen detail fields are disabled except the Selected column. I believe this is a behavior introduced by the use of PXProcessing type data view. Going against that behavior will likely not yield the desired result.
If the screen needs detail fields to be editable (except Selected column) I would advise not to create a processing screen. Using a PXSelect data view instead will provide correct behavior for the editable fields.
In the Activity / Task screen (cr306020), there is a 'Related Entity' field with a PXSelector lookup as well as a pencil for opening the screen of the related entity:
I'd like to know if there is a way to do this for a custom field. I've looked at the source code for the field (it's EPActivity.Source in the DAC), but I see nothing that puts these attributes on that field. No PXSelector or anything similar.
The example below shows how to add the Related Entity field on the Opportunities (CR304000) screen. Please be aware, PXRefNoteSelector control used in this sample is not currently supported by the Layout Editor in Acumatica Customization Manager. I used Opportunities to simplify and shorten the example. Unfortunately, for now you can only add the Related Entity field on a custom screen.
Now let's move forward to the sample:
Implement extension for the CROpportunity DAC to declare the database bound UsrRefNoteID and unbound RelatedEntity fields. Related Entity's NoteID will be stored in UsrRefNoteID, and RelatedEntity will be used to display Related Entity's user-friendly description:
public class CROpportunityExt : PXCacheExtension<CROpportunity>
{
#region UsrRefNoteID
public abstract class usrRefNoteID : IBqlField { }
protected Guid? _UsrRefNoteID;
[PXDBGuid]
[PXParent(typeof(Select<CRActivityStatistics,
Where<CRActivityStatistics.noteID, Equal<Current<CROpportunityExt.usrRefNoteID>>>>), LeaveChildren = true)]
public Guid? UsrRefNoteID
{
get
{
return _UsrRefNoteID;
}
set
{
_UsrRefNoteID = value;
}
}
#endregion
#region Source
public abstract class relatedEntity : IBqlField { }
[PXString(IsUnicode = true)]
[PXUIField(DisplayName = "Related Entity Description", Enabled = false)]
[PXFormula(typeof(EntityDescription<CROpportunityExt.usrRefNoteID>))]
public string RelatedEntity { get; set; }
#endregion
}
Create extension for the OpportunityMaint BLC to decorate its primary Opportunity data view with PXRefNoteSelectorAttribute. The PXRefNoteSelectorAttribute is required for the Edit (pencil) and Lookup buttons to work on your custom Related Entity field:
public class OpportunityMaintExt : PXGraphExtension<OpportunityMaint>
{
[PXCopyPasteHiddenFields(typeof(CROpportunity.resolution))]
[PXViewName(Messages.Opportunity)]
[PXRefNoteSelector(typeof(CROpportunity), typeof(CROpportunityExt.usrRefNoteID))]
public PXSelect<CROpportunity> Opportunity;
}
On Aspx page, add PXRefNoteSelector control with the DataField property set to RelatedEntity and NoteIDDataField to UsrRefNoteID.
For the EditButton, LookupButton and LookupPanel tags, use the primary data view name decorated with the PXRefNoteSelector attribute (Opportunity in the code snippet below)
<pxa:PXRefNoteSelector ID="edRefEntity" runat="server" DataField="RelatedEntity" NoteIDDataField="UsrRefNoteID"
MaxValue="0" MinValue="0" ValueType="Guid" CommitChanges="true">
<EditButton CommandName="Opportunity$Navigate_ByRefNote" CommandSourceID="ds" />
<LookupButton CommandName="Opportunity$Select_RefNote" CommandSourceID="ds" />
<LookupPanel DataMember="Opportunity$RefNoteView" DataSourceID="ds" TypeDataField="Type" IDDataField="NoteID" />
</pxa:PXRefNoteSelector>
Hide 3 actions generated by the PXRefNoteSelector attribute from the form toolbar. Use the same primary data view name decorated with the PXRefNoteSelector attribute (Opportunity in the code snippet below) as in the step above:
<CallbackCommands>
...
<px:PXDSCallbackCommand Name="Opportunity$Navigate_ByRefNote" Visible="False" />
<px:PXDSCallbackCommand Name="Opportunity$Select_RefNote" Visible="False" />
<px:PXDSCallbackCommand Name="Opportunity$Attach_RefNote" Visible="False" />
</CallbackCommands>
You might also need to implement your own EntityDescription operator, since at the time this example was created, it had internal access modifier and was not available outside of the PX.Objects.dll:
public class EntityDescription<RefNoteID> : BqlFormulaEvaluator<RefNoteID>, IBqlOperand
where RefNoteID : IBqlField
{
public override object Evaluate(PXCache cache, object item, Dictionary<Type, object> pars)
{
Guid? refNoteID = (Guid?)pars[typeof(RefNoteID)];
return new EntityHelper(cache.Graph).GetEntityDescription(refNoteID, item.GetType());
}
}
And finally... screenshot of the customized Opportunities screen with a brand-new Related Entity field:
I have the need in one of my customization to show a popup directly after the user modifies the value of one of the controls (in this case, a custom field in the SOLine of the Sales Order Entry screen). This popup shows some additional values in a grid that the user must select before completing the row.
Using the standard process a SmartPanel was added to the screen.
If I call this from an action / PXLookupButton, the popup shows and the grid is populated correctly.
If I move this to either the "FieldUpdated" or "RowSelected" event, the smartpanel is displayed however the grid is always empty. Once more, if I then click on the button the grid stays empty till I cancel the modifications and re-enter using only the button.
I tried calling the action's press method in these events as well but the same result occurs.
Watching SQL profiler and the debugger events I can see that the BQL statement is being executed and returning the correct rows it's just not displaying in the smartpanel's grid.
Is it possible to handle this type of request? I'm assuming I need to either move this to a different method and/or pass some additional values but haven't found the right combination.
This holds true on Acumatica 5.3 / 6.1
Any input would be appreciated.
RowUpdated handler allowed me to achieve requested behavior and show SmartPanel after field value change.
Example below relies on custom unbound Trigger Dialog field declared for the SOLine DAC. When a user checks or uncheckes Trigger Dialog flag, the system will show Item Quantity dialog to update Quantity for selected SOLine record:
public class SOLineExt : PXCacheExtension<SOLine>
{
#region TriggerDialog
public abstract class triggerDialog : PX.Data.IBqlField
{
}
[PXBool]
[PXUIField(DisplayName = "Trigger Dialog")]
public virtual bool? TriggerDialog { get; set; }
#endregion
}
Very basic SmartPanel declaration in Aspx:
<px:PXSmartPanel runat="server" ID="CstSmartPanel2" Key="SOLineParam" Caption="Item Quantity" AutoRepaint="True"
CaptionVisible="True" AcceptButtonID="CstButton6" AutoReload="true" >
<px:PXFormView runat="server" ID="CstFormView3" DataMember="SOLineParam" SkinID="Transparent" >
<Template>
<px:PXLayoutRule runat="server" StartColumn="True" />
<px:PXNumberEdit runat="server" ID="CstPXNumberEdit10" DataField="OrderQty" />
</Template>
</px:PXFormView>
<px:PXLayoutRule runat="server" StartRow="True" />
<px:PXPanel runat="server" ID="CstPanel5" SkinID="Buttons">
<px:PXButton runat="server" ID="CstButton6" DialogResult="OK" CommandName="ChangeOk" CommandSourceID="ds" />
<px:PXButton runat="server" ID="CstButton7" DialogResult="Cancel" Text="Cancel" />
</px:PXPanel>
</px:PXSmartPanel>
Accomplished with the SOOrderEntry BLC extension subscribing to RowUpdated handler for the SOLine DAC to show Item Quantity dialog to a user:
public class SOOrderEntryExt : PXGraphExtension<SOOrderEntry>
{
[Serializable]
public class SOLineParams : IBqlTable
{
#region OrderQty
public abstract class orderQty : PX.Data.IBqlField
{
}
[PXDBDecimal]
[PXDefault(TypeCode.Decimal, "0.0")]
[PXUIField(DisplayName = "Quantity")]
public virtual decimal? OrderQty { get; set; }
#endregion
}
public PXFilter<SOLineParams> SOLineParam;
public PXAction<SOOrder> ChangeOk;
[PXUIField(DisplayName = "OK")]
[PXButton(CommitChanges = true)]
protected void changeOk()
{
var lineParams = SOLineParam.Current;
Base.Transactions.Cache.SetValue<SOLine.orderQty>(Base.Transactions.Current, lineParams.OrderQty);
SOLineParam.Cache.Clear();
}
public void SOLine_RowUpdated(PXCache sender, PXRowUpdatedEventArgs e)
{
if (!sender.ObjectsEqual<SOLineExt.triggerDialog>(e.Row, e.OldRow) && e.ExternalCall == true)
{
SOLineParam.AskExt();
}
}
}
Another part of the extension class is ChangeOk action invoked by SmartPanel to update Quantity for selected record in the Document Details grid. To hide ChangeOk action from screen toolbar, it's also necessary to add the following command into PXDataSource.CallbackCommands collection:
<px:PXDSCallbackCommand Name="ChangeOk" Visible="False" />
I'm quite new to XAML trying to make grid with Toggle buttons
Something like this:
<GridView ItemSource="{Binding ButtonCollection}">
<GridView.ItemTemplate>
<DataTemplate>
<ToggleButton Content="{Binding Label}" IsEnabled="{Binding BEnabled}" IsChecked="{Binding BChecked, Mode=TwoWay}"/>
<DataTemplate>
</GridView.ItemTemplate>
</GridView>
I have
ObservableCollection<ButtonClass> ButtonCollection
also class for buttons
class ButtonClass
{
public string Label {get; set;}
public bool BEnabled {get; set:}
public bool BChecked {get;set;}
}
binding works when page loads buttons are displayed from ObservableCollection
But I want collection to update when button IsChecked value changes
also is there any way to bind function to click method like:
Click="{Binding DoWhenClicked}"
Now it just results in error I think that is because DoWhenClicked isn't in ItemSource.
Summary:
I want to have Grid of toggle buttons that binds to some sort of list/array/collection of data with label, checked status, enabled status.
When toggle button is checked I want it to reflect in my collection.
Also I want to bind event to Click method so that i can perform operations like disable some Toggle Buttons when other button is checked.
What is good way to do this.
I noticed that you asked several question about Template 10 before, so I supposed that you also used Template 10 here for MVVM pattern.
binding works when page loads buttons are displayed from ObservableCollection But I want collection to update when button IsChecked value changes
In Template 10 project, if you want to get notified when parameter in the data model (here means your ButtonClass), you can derive your class from BindableBase. If you check the BindableBase class you will find that it has done the work of INotifyPropertyChanged, it will be much easier here deriving from BindableBase directly rather than implementing INotifyPropertyChanged by yourself.
also is there any way to bind function to click method
Also I want to bind event to Click method so that i can perform operations like disable some Toggle Buttons when other button is checked.
Instead of Click event, I personally recommend you to using Command in MVVM pattern, and you may want to know which Button is clicked, so you can use CommandParameter here. I created a blank template 10 project and here is my sample:
<GridView x:Name="gridView" RelativePanel.Below="pageHeader" Margin="16,12,0,0" ItemsSource="{x:Bind ViewModel.ButtonCollection}">
<GridView.ItemTemplate>
<DataTemplate>
<ToggleButton Width="100" Content="{Binding Label}" IsEnabled="{Binding BEnabled}"
IsChecked="{Binding BChecked, Mode=TwoWay}" Command="{Binding ToggleBtnClickCommand}"
CommandParameter="{Binding Label}" />
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
The ButtonClass is like this:
public class ButtonClass : BindableBase
{
public string Label { get; set; }
public bool BEnabled { get; set; }
private bool _bChecked;
public bool BChecked
{
get { return _bChecked; }
set
{
_bChecked = value;
RaisePropertyChanged();
}
}
public ICommand ToggleBtnClickCommand { get; set; }
}
And the MainPageViewModel:
public class MainPageViewModel : ViewModelBase
{
public ObservableCollection<ButtonClass> ButtonCollection;
public MainPageViewModel()
{
ButtonCollection = new ObservableCollection<ButtonClass>();
for (int i = 0; i < 20; i++)
{
ButtonCollection.Add(new ButtonClass
{
Label = "TButton " + i,
BChecked = true,
BEnabled = true,
ToggleBtnClickCommand = new DelegateCommand<string>(ToggleBtnClicked)
});
}
}
public void ToggleBtnClicked(string obj)
{
var buttonLable = obj;
}
}
In case you need to check my sample, you can find my demo here.
There are a few concepts that are missing from your code that you need to properly implement for this to work
INotifyPropertyChanged -> Your ButtonClass class acts as a view model for your view. As such, for values to properly update UI and the other way around you need your class to implement it and all your properties to raise the PropertyChanged event when their values change (in the setter)
2-Way bindings -> If you want your ButtonClass instance to update when you click the button and you want your button to change state if you change the property in the ButtonClass, your bindings need to be Mode=TwoWay. You might want to explore the new Bindings {x:Bind} for better performance
Commands -> To bind the click event, you need to use the Command property. You would need to create a ICommand implementation, and create a property in your ButtonClass. The use Command property of the Button to bind to that Command.
Essentially, everything I mentioned are components of an MVVM framework, of which there are many out there. Here are some of the more popular ones: Caliburn, MVVMCross, Prism.
There's also a great starter kit for Windows 10 that will definitely kick start your app and contains a lot of this classes already built - Template10