How To Make UserControl In MasterPage Public For All Child Pages - user-controls

I have a UserControl which I have added to my web.config
<add tagPrefix="BCF" src="~/controls/MyMessageBox.ascx" tagName="error"/>
and added to my master page
<BCF:error ID="BCError" runat="server" Visible="false" />
Now I need to be able to reference this control AND its public properties from all child pages that use that masterpage. I did this is my BasePage OnLoad event
public UserControl BCError;
BCError = (UserControl)Master.FindControl("BCError");
Problem is, although I can do this in the .aspx page
BCError.Visible = true;
I cannot reference any of the Controls properties I have put in? Such as ShowError .. If I do
BCError.ShowError = "Error Message";
I just get an error saying
'System.Web.UI.UserControl' does not contain a definition for 'ShowInfo' and no extension method 'ShowInfo'
Can you please point me in the right direction!
This is the code for the user control... I can use the properties in the masterpage code behind (And in a page if I put the control directly into it) but cannot use them in the child page code behind?? It doesn't even show the properties or wrapper methods in the intellisense?
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
public partial class MyMessageBox : System.Web.UI.UserControl
{
#region Properties
public bool ShowCloseButton { get; set; }
#endregion
#region Load
protected void Page_Load(object sender, EventArgs e)
{
if (ShowCloseButton)
CloseButton.Attributes.Add("onclick", "document.getElementById('" + MessageBox.ClientID + "').style.display = 'none'");
}
#endregion
#region Wrapper methods
public void ShowError(string message)
{
Show(MessageType.Error, message);
}
public void ShowInfo(string message)
{
Show(MessageType.Info, message);
}
public void ShowSuccess(string message)
{
Show(MessageType.Success, message);
}
public void ShowWarning(string message)
{
Show(MessageType.Warning, message);
}
#endregion
#region Show control
public void Show(MessageType messageType, string message)
{
CloseButton.Visible = ShowCloseButton;
litMessage.Text = message;
MessageBox.CssClass = messageType.ToString().ToLower();
this.Visible = true;
}
#endregion
#region Enum
public enum MessageType
{
Error = 1,
Info = 2,
Success = 3,
Warning = 4
}
#endregion
}

Ok I think I reproduced roughly what your describing and I deleted my original answer cause it was way off.
What I found is that when you want a content page to reference a user control being used in a master page and the control is accesible and what not, you will get an error indicating that you need to reference a specific assembly, and then you get errors indicating that no Method exists of type such and such.
By adding the Register page directive on the child page to the user control resolved this issue. I reproduced this even with the control defined in the web.config or on the page. In both cases I still had to explicitly add a Register on the content page.
This doesn't make sense to me but it allowed my code to compile and work. Give it a shot let me know.
Once you do this you can reference the control like
this.Master.MessageBox.ShowInfo();
This assumes that you have a public property called MessageBox on the Master Page.
Edit
I've also found that this works much better if you register the control on both the master and the content page and not use the web.config.
Edit
If you don't want your child page to reference the user control your other option is expose methods on the master page like ShowInfo() which would delegate to the user control.

You need to declare it as your control type to access it's properties.
public MyMessageBox BCError;
BCError = (MyMessageBox )Master.FindControl("BCError");

Try using this in the pages that inherit from your master page:
<%# MasterType VirtualPath="~/MasterPageName.Master" %>

Related

Render Action button

I was creating a new Screen with the FormDetail template where I would be having a Filter DAC and list of DAC to display on Grid. I created the page successfully. Then,I wanted to put a button on the top of the button which would pull data from api and refresh grid. So, I wrote the below code to render an action button on page(FormDetail) like this.
But, it is not working.
using System;
using PX.Data;
namespace AcumaticaSquarePOSIntegration
{
public class SquarePOSTransactionInquiry : PXGraph<SquarePOSTransactionInquiry>
{
public PXSave<MasterTable> Save;
public PXCancel<MasterTable> Cancel;
public PXFilter<MasterTable> MasterView;
public PXFilter<DetailsTable> DetailsView;
public PXAction<MasterTable> Calc;
[PXUIField(DisplayName="Calc")]
[PXButton]
protected virtual IEnumerable calc(PXAdapter adapter)
{
return adapter.Get();
}
[Serializable]
public class MasterTable : IBqlTable
{
}
[Serializable]
public class DetailsTable : IBqlTable
{
}
}
}
I even tried add
Is there anything that I am missing here?
You have two PXFilters, change the second to PxSelect and make the PXFilter your first Data view in the list.
try using PXProcessButton instead of PXButton.
Also make sure MasterView is specified in aspx as a PrimaryView.

Automatically calculating and adding Landedcost

I need to add a LandedCost in PO Receipt screen (PO302000) based on a fix percentage (which I can include as a custom field in PO Preferences). It should be automatically added by the time PO Receipt is released. Which event should be the best approach to trigger and add LandedCost?
Is that when user uncheck OnHold checkbox?
Or, User clicks on Release button? If yes then can I extend release action?
The method that releases the POReceipts is static we cannot override it.
However, we can override the places where this static method is being called. It is called in two places: 1) on the release Action of POReceiptEntry(graph) and 2) on the constructor of the POReleaseReceipt(graph) that sets the process delegate.
1) On the POReceiptEntry, you can extend this graph to first do your Custom code and then call base release method.
public class POReceiptEntry_Extension:PXGraphExtension<POReceiptEntry>
{
public PXSetup<POSetup> posetup;
#region Event Handlers
public PXAction<POReceipt> release;
[PXUIField(DisplayName = Messages.Release, MapEnableRights = PXCacheRights.Update, MapViewRights = PXCacheRights.Update)]
[PXProcessButton]
public virtual void Release()
{
//retrieve value from Custom field added on PO Preferences screen
//POSetup setup = posetup.Current;
//POSetupExt setupExt = setup.GetExtension<POSetupExt>();
LandedCostTran landedCost = Base.landedCostTrans.Insert();
landedCost.LandedCostCodeID = "YOURLANDEDCOSTCODE";
landedCost.InvoiceNbr = "YOURINVOICENUMBER";
landedCost.CuryLCAmount = 2; //Formula here using setupExt.UsrFieldPercentange
Base.landedCostTrans.Update(landedCost);
Base.release.Press();
}
#endregion
}
2) On the POReleaseReceipt graph, since the process delegate is set on the constructor of this graph, you can extend this graph and override Initialize() method to set your custom process delegate.
Your custom process delegate will have your custom code and then call base method.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Text;
using PX.Common;
using PX.Data;
using PX.Objects.CS;
using PX.Objects.IN;
using PX.Objects.AP;
using PX.Objects.PO;
using PX.Objects.GL;
using PX.Objects.CM;
using PX.Objects;
namespace PX.Objects.PO
{
public class POReleaseReceipt_Extension:PXGraphExtension<POReleaseReceipt>
{
public override void Initialize()
{
//Gets Process Delegate
var processDelegate = (PXProcessingBase<POReceipt>.ProcessListDelegate)Base.Orders.GetProcessDelegate();
//Change the process delegate that was created by the framework by your custom one.
Base.Orders.SetProcessDelegate(delegate (List<POReceipt> orders) { POReceiptsProc(orders, processDelegate); });
}
public static void POReceiptsProc(List<POReceipt> orders, PXProcessingBase<POReceipt>.ProcessListDelegate processDelegate)
{
//Execute your custom code here
//create POReceiptEntry graph, Loop through the orders, Access your Custom field, Add LandedCost
PXTrace.WriteInformation("Start Process execution");
POReceiptEntry graph = PXGraph.CreateInstance<POReceiptEntry>();
........
//Call the base action
if (processDelegate != null)
processDelegate(orders);
}
}
}

MvvmCross and UIButton.Selected UISegmentedControl Bindings, iOS

In a cross platform Xamarin app built with the MvvmCross framework I'm using a ToggleButton Widget in an Android .axml layout. I've bound the Checked property to a View Model property using a converter using the following binding syntax:
Checked MarketBuySellViewModel.Direction, Converter=DirectionBool, ConverterParameter='Sell'
Everything works well. On the iOS side, it appears you can use UIButton as a ToggleButton by using the Selected property. This implies that the following binding should achieve what I want on iOS:
set.Bind (SellButton).For(b => b.Selected).To (vm => vm.MarketBuySellViewModel.Direction).WithConversion("DirectionBool", "Sell");
I don't get any binding errors in the application output but the binding itself doesn't seem to work. Clicking the button doesn't set the Direction property and setting the direction to a different value does not set the Selected property on the UIButton.
Do I need to create a Custom Binding or am I simply setting up the binding incorrectly?
I also tried using a UISegmentedControl to achieve the same effect. Is binding to this control supported at all in MvvmCross? I don't see any reference to it in the source code. Does this mean I need to create custom bindings for it too?
For the UIButton, I don't believe there's any included Selected binding built into MvvmCross. Because of this - and because Selected doesn't have a simple paired event SelectedChanged, then I believe Selected binding should work one-way (from ViewModel to View) but not two-way.
There is a binding for the On of a UISwitch control and that's the control I've seen used most in these situations.
If you wanted to add a custom 2-way binding for Selected then I guess you'd have to do this using the ValueChanged event (but would need to check that is correct).
To do so, you'd just build a target binding something like:
public class MvxUIButtonSelectedTargetBinding : MvxPropertyInfoTargetBinding<UIButton>
{
public MvxUIButtonSelectedTargetBinding(object target, PropertyInfo targetPropertyInfo)
: base(target, targetPropertyInfo)
{
var view = View;
view.ValueChanged += HandleValueChanged;
}
private void HandleValueChanged(object sender, System.EventArgs e)
{
var view = View;
if (view == null)
return;
FireValueChanged(view.Selected);
}
public override MvxBindingMode DefaultMode
{
get { return MvxBindingMode.TwoWay; }
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (isDisposing)
{
var view = View;
if (view != null)
{
view.ValueChanged -= HandleValueChanged;
}
}
}
}
and this could be registered in Setup in protected override void FillTargetFactories(IMvxTargetBindingFactoryRegistry registry) using something like:
registry.RegisterPropertyInfoBindingFactory(typeof(MvxUIButtonSelectedTargetBinding), typeof(UIButton),
"Selected");
Similarly, I don't believe anyone has added a two way UISegmentedControl binding yet - but would happily see one added.
Building a two way UISegmentedControl binding would be quite straight-forward - you'd just have to bind to the pair SelectedSegment and ValueChanged - with code similar to above.
Alternatively, you could switch to using a custom MySegmentedControl which had a nicer Value`ValueChanged` pair which would automatically work without a custom binding - e.g.:
public class MySegmentedControl : UISegmentedControl
{
// add more constructors if required
public int Value
{
get { return base.SelectedSegment; }
set { base.SelectedSegment = value; }
}
}
If any or all of these custom bindings are needed, then the Mvx project is happy to get these bindings added as issues or pull requests along with test/demo UIs in the https://github.com/slodge/MvvmCross-Tutorials/blob/master/ApiExamples/ApiExamples.Touch/Views/FirstView.cs project
Could be helpful to someone else, so i'm sharing my experience. I needed a two way binding for UISegmentedControl.SelectedSegment property to a ViewModel. The one way biding (ViewModel => View) works by default. I couldn't able to properly utilize the solution proposed by Stuart - to subclass the UISegmentedControl. I tried to ensure that the linker does not rip off the new custom control code, but this didn't help me a bit. So a perfectly viable solution is the one with MvxPropertyInfoTargetBinding. Here is the code working ok for me:
public class MvxUISegmentedControlSelectedSegmentTargetBinding : MvxPropertyInfoTargetBinding<UISegmentedControl>
{
public MvxUISegmentedControlSelectedSegmentTargetBinding(object target, PropertyInfo targetPropertyInfo)
: base(target, targetPropertyInfo)
{
this.View.ValueChanged += HandleValueChanged;
}
private void HandleValueChanged(object sender, System.EventArgs e)
{
var view = this.View;
if (view == null)
{
return;
}
FireValueChanged(view.SelectedSegment);
}
public override MvxBindingMode DefaultMode
{
get { return MvxBindingMode.TwoWay; }
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (isDisposing)
{
var view = this.View;
if (view != null)
{
view.ValueChanged -= HandleValueChanged;
}
}
}
}
public class Setup : MvxTouchSetup
{
...
protected override void FillTargetFactories(IMvxTargetBindingFactoryRegistry registry)
{
registry.RegisterPropertyInfoBindingFactory(typeof(MvxUISegmentedControlSelectedSegmentTargetBinding), typeof(UISegmentedControl), "SelectedSegment");
}
}

How do I create a program that details files and their sub directories?

There is a program that I am working on and Im absolutly lost even at how to begin this. I am using Visual Studio C# Windows App Form.
What I need to do is allow the user to enter any path location they want and the program will return the Name of the file/folder; Path; date and size, and this will also be done for sub directories.
I found some code in the MSDN site and I am trying to use it and modify it for the first part of this project, but keep receiving error messages. Some of the messages indicate that there is more than one entry ie (static void Main() and using namespace Detailed).
This is what I have so far, a form with rich text box and the FolderBrowserDialog and it seems as I can't get beyond this point without so many errors.
This is under Form1.Designer.cs:
<i>namespace Detailed
{
partial class Form1
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.folderBrowserDialog1 = new System.Windows.Forms.FolderBrowserDialog();
this.richTextBox1 = new System.Windows.Forms.RichTextBox();
this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog();
this.SuspendLayout();
//
// folderBrowserDialog1
//
this.folderBrowserDialog1.HelpRequest += new System.EventHandler(this.folderBrowserDialog1_HelpRequest);
//
// richTextBox1
//
this.richTextBox1.Location = new System.Drawing.Point(12, 32);
this.richTextBox1.Name = "richTextBox1";
this.richTextBox1.Size = new System.Drawing.Size(167, 23);
this.richTextBox1.TabIndex = 0;
this.richTextBox1.Text = "";
//
// openFileDialog1
//
this.openFileDialog1.FileName = "openFileDialog1";
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(284, 262);
this.Controls.Add(this.richTextBox1);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.FolderBrowserDialog folderBrowserDialog1;
private System.Windows.Forms.RichTextBox richTextBox1;
private System.Windows.Forms.OpenFileDialog openFileDialog1;
}
}
For the For1.cs this is what I have so far:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
public class FolderBrowserDialogExampleForm : System.Windows.Forms.Form
{
private FolderBrowserDialog folderBrowserDialog1;
private OpenFileDialog openFileDialog1;
private RichTextBox richTextBox1;
private MainMenu mainMenu1;
private MenuItem fileMenuItem, openMenuItem;
private MenuItem folderMenuItem, closeMenuItem;
private string openFileName, folderName;
private bool fileOpened = false;
public partial class Form1 : Form
{
public Form1()
{
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void folderBrowserDialog1_HelpRequest(object sender, EventArgs e)
{
}
}
private void InitializeComponent()
{
this.SuspendLayout();
//
// FolderBrowserDialogExampleForm
//
this.ClientSize = new System.Drawing.Size(284, 262);
this.Name = "FolderBrowserDialogExampleForm";
this.ResumeLayout(false);
}
}
I'm still new to programing and hope I can get this figured out asap as I was requested to have this no later than Thursday morning est. I had the Rich TextBox in the Form, but removed it because of too many errors.
This is the code I found. I know this is just part of what I need to do, but when reading through the code I noticed that maybe I can apply what is needed to the form and then break up the code and put the pieces of code where I need them. This is the code I am following
Here is an error message I am receiving with Form1.Designer.cs - there are 14 of these same errors:
‘Detailed.form1’ does not contain a definition for ‘Form1_Load’ and no extension method ‘Form1_Load’ accepting a first argument of type ‘Detailed.Form1’ could be found (are you missing a using directive or an assembly reference?)
The first thing you want is a dialog prompting the user for a directory.
So get rid of all that code, start a new project win form and place a textbox in your form and a button in your form.
Simple enough one text box and one button. Now in the click event of your button "Browse", have you, you write code to open an instance of the FolderBrowserDialog class and you .ShowDialog().
To get this path:
Here is a sample screen output:
The code is fairly straightforward, look at my picture and how much code i have to do this.

My webpart event handling does not fire in SharePoint

I started coding something complicated and then realized my event handlers don't work, so I super simplified a button with an event handler. Please see the code below and maybe you can tell me why it doesn't fire?
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using System.Web.UI.WebControls;
namespace PrinterSolution
{
[Guid("60e54fde-01bd-482e-9e3b-85e0e73ae33d")]
public class ManageUsers : Microsoft.SharePoint.WebPartPages.WebPart
{
Button btnNew;
protected override void CreateChildControls()
{
btnNew = new Button();
btnNew.CommandName = "New";
btnNew.CommandArgument = "Argument";
btnNew.Command += new CommandEventHandler(btnNew_Command);
this.Controls.Add(btnNew);
}
void btnNew_Command(object sender, CommandEventArgs e)
{
ViewState["state"] = "newstate";
}
//protected override void OnLoad(EventArgs e)
//{
// this.EnsureChildControls();
//}
}
}
I had a similar problem. In my case the button was contained in a panel and although buttons on the parent control worked correctly the button on the child Panel control didn't.
It turns out that you need to call EnsureChildControls in the OnLoad method in the child panel to ensure that CreateChildControls is called early enough in the life cycle of the page so that controls can respond to events. This is described briefly in this answer here which is where I discovered the solution to my problem.
Following this instruction I just added the following code to my panel control:
protected override void OnLoad(EventArgs e)
{
EnsureChildControls();
base.OnLoad(e);
}
I notice that there appears to be a lot of confusion about this issue in the forums so to demonstrate that this works I added trace statements to my code. Below are the results from the before and after cases. Note that the position of Survey list creating child controls moves from within the PreRender event to within the Load event.
Before:
After:

Resources