In a page when we will click the component Presentation tab we can see the component and template listed there.On clicking of Insert button just below that, it will open another window "Insert component presentation" there also we will have Insert and close button.So now what i need to do While inserting i need to check whether the combination of selected Component and Template is already present there on page or not. If yes then it should prevent inserting the same with a popup like "this combination is already present, select other componet".
Any idea how can i proceed. How can i trigger a Javascript on the Insert button?
EDIT:
When i am subscrbing it to Page i am getting erro.My code :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Text;
using Tridion.ContentManager.Extensibility.Events;
using Tridion.ContentManager.Extensibility;
using Tridion.ContentManager.ContentManagement;
using System.IO;
using System.Windows.Forms;
namespace MyEventHandlers
{
[TcmExtension("MyEventHandlerExtension")]
public class MyEventHandler : TcmExtension
{
public MyEventHandler()
{
Subscribe();
}
public void Subscribe()
{
EventSystem.Subscribe<Page, SaveEventArgs>(SaveBtnInitiated, EventPhases.Initiated);
}
private void SaveBtnInitiated(Page subject, SaveEventArgs args, EventPhases phase)
{
try
{
List<string> allcplist = new List<string>();
List<string> allcplist = new List<string>();
foreach (ComponentPresentation cp in subject.ComponentPresentations)
{
allcplist.Add(cp.Component.Id + "," + cp.ComponentTemplate.Id);
}
List<string> uniquecplist = allcplist.Distinct().ToList();
if (allcplist.Count != uniquecplist.Count)
{
subject.Checkin(false);
throw new Exception("Page has duplicate component presentation");
}
catch(Exception)
{
}
}
You can implement this in an event handler that is subscribed to the Page Save event and the Initiated phase. When there is a duplicate Component Presentation you can cancel the Save by throwing an exception. The message will be shown in the Message Center in the TCM Explorer.
Why are you subscribing to the Component? I think it should be the Page. Then you can walk through the ComponentPresentations property.
Code to go through the Component Presentations and throw an exception when duplicate presentations are found:
foreach (var cpA in subject.ComponentPresentations)
{
if (subject.ComponentPresentations.Where(cpB => ComponentPresentationsAreEqual(cpA, cpB)).ToList().Count() > 2)
{
throw new DuplicateComponentPresentationsEmbeddedOnPageException();
}
}
And the function to include cpB in the list when it is equal to cpA:
function ComponentPresentationsAreEqual(ComponentPresentation cpA, ComponentPresentation cpB)
{
return cpA.Component.Id == cpB.Component.Id && cpA.ComponentTemplate.Id == cpB.ComponentTemplate.Id;
}
I got my Result with this code Thanks to #Arjen Stobbe
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Text;
using Tridion.ContentManager.Extensibility.Events;
using Tridion.ContentManager.Extensibility;
using Tridion.ContentManager.ContentManagement;
using System.IO;
using System.Windows.Forms;
namespace MyEventHandlers
{
[TcmExtension("MyEventHandlerExtension")]
public class MyEventHandler : TcmExtension
{
public MyEventHandler()
{
Subscribe();
}
public void Subscribe()
{
EventSystem.Subscribe<Page, SaveEventArgs>(SaveBtnInitiated, EventPhases.Initiated);
}
private void SaveBtnInitiated(Page subject, SaveEventArgs args, EventPhases phase)
{
try
{
List<string> allcplist = new List<string>();
List<string> allcplist = new List<string>();
foreach (ComponentPresentation cp in subject.ComponentPresentations)
{
allcplist.Add(cp.Component.Id + "," + cp.ComponentTemplate.Id);
}
List<string> uniquecplist = allcplist.Distinct().ToList();
if (allcplist.Count != uniquecplist.Count)
{
subject.Save(false);
throw new Exception("Page has duplicate component presentation");
}
catch(Exception)
{
}
}
But i am not deleting the duplicate CP present on the page. Do i need to add,
for each()
inside
if (allcplist.Count != uniquecplist.Count)
{
}
Related
I have three pages at the moment in my app. I will call them EventsPage, NewEventPage, and ListPage. EventsPage is the first page of the app and you can open a NewEventPage from there. On this NewEventPage is a button that pops the NewEventPage from the stack and is supposed to create a ListPage immediately afterward, but the ListPage is not appearing, although I found out that its constructor is running.
Here's the code for the NewEventPage:
using Partylist.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace Partylist.Views
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class NewEventPage : ContentPage
{
// Constructor.
public NewEventPage()
{
InitializeComponent();
}
// Event handlr for when the "Cancel" button is clicked.
async void OnCancelClicked(object sender, EventArgs e)
{
// Goes back to the previous page.
await Navigation.PopAsync();
}
// Event handler for when the "Create" button gets clicked.
async void OnCreateClicked(object sender, EventArgs e)
{
// Make sure there is something in the text entry.
if (string.IsNullOrWhiteSpace(EventNameEntry.Text))
{
// If there is nothing there, print an error message.
ErrorLabel.Text = "Your event needs a name!";
}
// If there is something in the text entry, try to create
// a new event with the text as its name.
else
{
// Variable to store the created event.
Event newEvent = new Event();
// Variable to store its folder.
DirectoryInfo newEventFolder;
// Flag to see if the event was created sccessfully.
bool eventCreated;
try
{
// If there's already an event with that name, let the
// user know.
if
(Directory.Exists(Path.Combine(Environment.GetFolderPath
(Environment.SpecialFolder.LocalApplicationData),
EventNameEntry.Text)))
{
ErrorLabel.Text = "You already have an event with that name.";
eventCreated = false;
}
// Otherwise, try to creaate the folder.
else
{
newEventFolder = Directory.CreateDirectory(
Path.Combine(Environment.GetFolderPath
(Environment.SpecialFolder.LocalApplicationData),
EventNameEntry.Text));
// Then, create the event based on that folder.
newEvent = new Event
{
FolderName = EventNameEntry.Text,
DateCreated = newEventFolder.CreationTime,
DateEdited = newEventFolder.LastWriteTime
};
// Get rid of any error messages that might be on screen.
ErrorLabel.Text = "";
eventCreated = true;
}
}
// Should throw an ArgumentException in most cases where there is
// an invalid character.
catch (ArgumentException)
{
// Get all the invalid characters and turn them into a string.
char[] invalidChars = Path.GetInvalidPathChars();
string invalid = "";
foreach(char currentChar in invalidChars)
{
invalid += currentChar;
}
// Change the text of the error label.
ErrorLabel.Text = "Your event name can't have these characters: \""
+ invalid + "\".";
eventCreated = false;
}
// If the event was created successfully, select it, pop the "New Event"
// page, and open a "List" page for the event.
if (eventCreated)
{
App.selectedEvent = newEvent;
await Navigation.PopAsync();
await Navigation.PushAsync(new ListsPage());
}
}
}
}
}
And here's the code for the ListPage:
using Partylist.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace Partylist.Views
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class ListsPage : ContentPage
{
// List of lists, used to populate
// the page's ListView (see the XAML).
public ObservableCollection<PartylistList> ListList { get; set; }
// Constructor.
public ListsPage()
{
// Does all the stuff to make the page
// exist that doesn't involve anything
// specific to this particular page in
// this particular app.
InitializeComponent();
}
// Override for OnAppearing().
protected override void OnAppearing()
{
// Regular OnAppearing() method.
base.OnAppearing();
// Set the title to be the name of the selected event.
Title = App.selectedEvent.FolderName;
// Set the BindingContext of the page to itself.
this.BindingContext = this;
// Set the ItemsSource of the ListView in the
// XAML to the ObservableCollection.
ListList = new ObservableCollection<PartylistList>();
ListListView.ItemsSource = ListList;
// Loop to populate the ObservableCollection.
for (int i = 0; i < Directory.GetFiles(
Path.Combine(Environment.GetFolderPath
(Environment.SpecialFolder.LocalApplicationData),
App.selectedEvent.FolderName))
.Length; i++)
{
// Add a new list.
ListList.Add(new ContactList());
// Set the filename to the name of the file
// that the list corresponds to.
ListList.ElementAt(i).Filename =
Directory.GetFiles(
Path.Combine(Environment.GetFolderPath
(Environment.SpecialFolder.LocalApplicationData),
App.selectedEvent.FolderName))[i];
// Sets the date/time created to the file's
// creation date.
ListList.ElementAt(i).DateCreated = Directory
.GetCreationTime(Directory.GetFiles(
Path.Combine(Environment.GetFolderPath
(Environment.SpecialFolder.LocalApplicationData),
App.selectedEvent.FolderName))[i]);
// Sets the date/time last edited to the
// folder's write date.
ListList.ElementAt(i).DateEdited = Directory
.GetLastWriteTime(Directory.GetFiles(
Path.Combine(Environment.GetFolderPath
(Environment.SpecialFolder.LocalApplicationData),
App.selectedEvent.FolderName))[i]);
}
}
}
}
We had CefSharp calling a project deployed on IIS. That worked. And a cookie I need for the third party library is loaded successfully.
Now we want CefSharp to load the same html and third party library through disk, bypassing IIS. Files are loading and running complete with functioning javascript, however the third party library requires a "domain name" to match the one associated with the license.
I need my domain name to match the one on my license which was generated with domain=localhost. But once I specify a domain name, the page, including the license checker, doesn't load.
This is a related problem. A cookie I need to load loads succesfully when I use csharp to call the IIS project, but fails when I open up the html project from disk. For reference, static void FrameLoaded is the same cookie loading procedure used in both versions of my project.
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace MinRepExample2
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using CefSharp;
using CefSharp.WinForms;
namespace MinRepExample2
{
public partial class Form1 : Form
{
private ChromiumWebBrowser browser;
public Form1()
{
InitializeComponent();
try
{
string siteURL = "";
string FileBase = #"c:\users\romero.ryan\documents\visual studio 2015\Projects\MinRepExample2";
string CacheDir = FileBase+#"\Cef2";
// CefSettings to temporarily reduce security
CefSettings MySettings = new CefSettings();
MySettings.CachePath = CacheDir;
MySettings.CefCommandLineArgs.Add("enable-media-stream", "enable-media-stream");
MySettings.CefCommandLineArgs.Add("allow-file-access-from-files", "allow-file-access-from-files");
MySettings.CefCommandLineArgs.Add("disable-web-security", "disable-web-security");
MySettings.JavascriptFlags = "--expose-wasm";
// Browser Settings
BrowserSettings browserSettings = new BrowserSettings();
browserSettings.FileAccessFromFileUrls = CefState.Enabled;
browserSettings.LocalStorage = CefState.Enabled;
browserSettings.UniversalAccessFromFileUrls = CefState.Enabled;
browserSettings.WebSecurity = CefState.Disabled;
// Custom Scheme Registration
MySettings.RegisterScheme(new CefCustomScheme
{
SchemeName = MySchemeHandlerFactory.SchemeName,
SchemeHandlerFactory = new MySchemeHandlerFactory(),
IsFetchEnabled = true,
IsLocal = false,
IsCorsEnabled = true,
IsSecure = true,
//DomainName= #"\Users\romero.ryan"
DomainName = "localhost"
});
CefSharpSettings.LegacyJavascriptBindingEnabled = true;
if (!Cef.IsInitialized)
{
Cef.Initialize(MySettings);
}
//string fName = #"C:\Users\romero.ryan\Documents\Visual Studio 2015\Projects\WinHostScandit1\WebHostOnDisk\CefPrimeFiles";
//c:\users\romero.ryan\documents\visual studio 2015\Projects\MinRepExample2\TestSite.html
browser = new ChromiumWebBrowser(#"fileProtocol:\\" + FileBase + "\\TestSite.html");
browser.BrowserSettings = browserSettings;
browser.Dock = DockStyle.Fill;
browser.Name = "browser";
browser.LoadingStateChanged += FrameLoaded;
this.Controls.Add(browser);
}
catch (Exception ex)
{
throw ex;
}
}
public void FrameLoaded(object sender, LoadingStateChangedEventArgs e)
{
//ChromiumWebBrowser ans = (ChromiumWebBrowser)Controls.Find("browser", false).First();
if (!e.IsLoading)
{
// CefSharp specific Cookie manipulation to register app as single device used with Scandit Library.
// ADD Cookie in C# code. Also adding in javascript code
var cookman = browser.GetCookieManager();
string[] schemes = { "fileProtocol", "fileprotocol", "fileprotocol:", "fileProtocol:" };
cookman.SetSupportedSchemes(schemes, true);
CefSharp.Cookie cook1 = new CefSharp.Cookie();
cook1.Domain = "localhost";
cook1.Name = "scandit-device-id";
cook1.Value = "ffaf4f340998d137fc260d563004eabcd388e90f";
cook1.Path = "/scanditpage";
cook1.Expires = new DateTime(2029, 6, 17);
// cookman.SetCookieAsync(ConfigurationManager.AppSettings["ScanditURL"], cook1);
var respcook = cookman.SetCookieAsync("http://localhost/scanditpage/ScanditTest.html", cook1);
bool cookieSet = cookman.SetCookie("http://localhost/scanditpage/ScanditTest.html", cook1);
CefSharpSettings.LegacyJavascriptBindingEnabled = true;
//cookman.SetCookie
// Adding Test cookie
browser.ExecuteScriptAsync("TestAddCookie()");
// Launches Dev tools for Debugging Purposes.
browser.ShowDevTools();
}
}
}
}
MySchemeHandler.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CefSharp;
using System.IO;
namespace MinRepExample2
{
public class MySchemeHandler : ResourceHandler
{
public const string SchemeName = "fileProtocol";
private string folderPath;
public MySchemeHandler()
{
folderPath = "";
}
public override CefSharp.CefReturnValue ProcessRequestAsync(IRequest request, ICallback callback)
{
var uri = new Uri(request.Url);
string fileName = uri.LocalPath;
var requestedFilePath = "C:/" + fileName;
string bFileName = "";
bFileName = requestedFilePath;
if (File.Exists(bFileName))
{
byte[] bytes = File.ReadAllBytes(bFileName);
Stream = new MemoryStream(bytes);
var fileExtension = Path.GetExtension(bFileName);
MimeType = GetMimeType(fileExtension);
return CefReturnValue.Continue;
//return true;
}
else
{
throw new FileNotFoundException();
}
callback.Dispose();
return CefReturnValue.Continue;
}
}
}
MySchemeHandlerFactory:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CefSharp;
namespace MinRepExample2
{
public class MySchemeHandlerFactory: ISchemeHandlerFactory
{
public const string SchemeName = "fileProtocol";
public IResourceHandler Create(IBrowser browser, IFrame frame, string schemeName, IRequest request)
{
return new MySchemeHandler();
}
}
}
Testing HTML:
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>Test Site for CefSharp Cookies</title>
<script type="text/javascript">
function AddCookie(name, value) {
// Add cookie as name value pair.
var newcookie = name + "=" + value + ";";
document.cookie=newcookie
}
function TestAddCookie() {
// Add specific cookie. Called from executescript in FrameLoaded method
AddCookie("name", "everlast");
}
function ButtonCookie() {
//Adds cookie by button click, then displays all available cookies.
AddCookie("button", "clicked");
var decodedCookie = decodeURIComponent(document.cookie);
alert(decodedCookie);
}
</script>
</head>
<body>
<div>Hello, World!</div>
<button onclick="ButtonCookie();">Add Cookie</button>
</body>
</html>
I figured it out from advice from amaitland and this answer: Simple Custom Scheme.
CefSettings allows you to set permissions like allowing CORS and Fetch for loading WASM files. CefSettings is also used for registering custom scheme handlers. Some schemes might need special permissions to load dependent javascript libraries. Permissions associated with this variable must be set before calling Cef.Initialize. Cef.Initialize should not be called after new ChromiumWebBrowser();
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using CefSharp;
using CefSharp.WinForms;
using CefSharp.SchemeHandler;
namespace EpmsMobileWF.ScanditWebForm
{
public partial class ScanditPopupForm : Form
{
public static ScanditPopupConfig scanditConfigs;
public static JSObj1 mess;
public ChromiumWebBrowser browser;
public ScanditPopupForm(TextBox inForm)
{
InitializeComponent();
InitScanner();
mess = new JSObj1(inForm, this);
}
public void InitScanner()
{
scanditConfigs = new ScanditPopupConfig();
var settings = new CefSettings();
FolderSchemeHandlerFactory newFac = new FolderSchemeHandlerFactory(scanditConfigs.HTMLRootFolder,null, scanditConfigs.DomainName, "ScanditTest.html");
CefCustomScheme ScanditScheme = new CefCustomScheme
{
SchemeName = "http",
DomainName = scanditConfigs.DomainName,
SchemeHandlerFactory = newFac,
};
ScanditScheme.IsCorsEnabled = true;
ScanditScheme.IsFetchEnabled = true;
ScanditScheme.IsLocal = true;
ScanditScheme.IsStandard = true;
settings.CachePath = scanditConfigs.ScanditCacheDirectory;
settings.CefCommandLineArgs.Add("enable-media-stream", "enable-media-stream");
settings.CefCommandLineArgs.Add("allow-file-access-from-files", "allow-file-access-from-files");
settings.PersistSessionCookies = true;
settings.JavascriptFlags = "--expose-wasm";
settings.RegisterScheme(ScanditScheme);
Cef.Initialize(settings);
browser = new ChromiumWebBrowser(scanditConfigs.ScanditURL);
this.Controls.Add(browser);
browser.Dock = DockStyle.Fill;
}
}
}
I have a schema in Tridion which have embedded schema fields which may further have embedded fields in there.
I want to reach final leaf field so that I can assign some value to it. For that I want to write recursive function which loop through each and every field until it reaches a final field.
I am implementing using the Core Service in SDL Tridion 2011
My code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ServiceModel;
using System.Net;
using System.Xml;
using Tridion.ContentManager.CoreService.Client;
using System.Text;
using Tridion.ContentManager.CoreService;
using System.ServiceModel.Channels;
using System.IO;
using System.Collections;
using System.Text.RegularExpressions;
using System.Xml.Linq;
using System.Data.OleDb;
using System.Data;
using System.Configuration;
namespace Loading_Utility
{
public partial class TST : System.Web.UI.Page
{
Fields obj = new Fields();
protected void Page_Load(object sender, EventArgs e)
{
using (ChannelFactory<ISessionAwareCoreService> factory =
new ChannelFactory<ISessionAwareCoreService>("wsHttp_2011"))
{
ISessionAwareCoreService client = factory.CreateChannel();
var schemaFields = client.ReadSchemaFields("tcm:202-2242-8", true, new ReadOptions());
ComponentData component = (ComponentData)client.GetDefaultData(ItemType.Component, "tcm:202-638-2");
var fields = Fields.ForContentOf(schemaFields);
component.Schema.IdRef="tcm:202-2242-8";
}
}
public void fieldRecursion(Field field)
{
//var getFields = fields;
if (field.GetType() == typeof(EmbeddedSchemaFieldDefinitionData))
{
// code for checking further if field is embedded or not
//Field newField = field.GetSubFields().GetFieldElements( new ItemFieldDefinitionData() as Field)
//fieldRecursion(recursiveField);
}
//string fieldName = recursiveField.Name;
//fields[fieldName] = "HI";
}
}
}
Whilst I don't have the solution you are looking for, I see you're using the core service, personally I prefer to get hold of the Component XML (Component.Content) and parse/manipulate it as I need. Perhaps if you can paste the XML here I can drop it into one of my sample core service projects and send you a solution back?
In the event that doesn't help you, i've had a look at the api, and this should help you get going in the right path. Perhaps once you have a solution you could paste it here?
public void RecurseEmbeddedFields(SchemaFieldsData schemaFields)
{
foreach (ItemFieldDefinitionData field in schemaFields.Fields)
{
if (field.GetType() == typeof(EmbeddedSchemaFieldDefinitionData))
{
// check if this field contains more embedded fields
// if it does recurse
}
}
}
OK, I felt a bit guilty about not helping, but I still stand by my view that this is not a Tridion-related question and that you should try getting some more experience with general development practices.
Here's an example of how to load the Component's content, then read it recursively using Xml:
Xml of the component:
<Content xmlns="uuid:02395f72-acef-44e8-9c35-ff8c9f380251">
<EmbeddedSchema1>
<SomeField>Hello</SomeField>
<EmbeddedSchema2>
<ATextField>There</ATextField>
</EmbeddedSchema2>
</EmbeddedSchema1>
</Content>
Core Service code:
static void Main(string[] args)
{
SessionAwareCoreServiceClient client = new SessionAwareCoreServiceClient("wsHttp_2011");
ReadOptions readOptions = new ReadOptions();
ComponentData component = (ComponentData)client.Read("tcm:5-3234", readOptions);
Console.WriteLine("Find fields recursively");
XmlDocument content = new XmlDocument();
content.LoadXml(component.Content);
SchemaData schema = (SchemaData)client.Read(component.Schema.IdRef, readOptions);
XmlNamespaceManager ns = new XmlNamespaceManager(new NameTable());
ns.AddNamespace("content", schema.NamespaceUri);
foreach (XmlElement node in content.SelectNodes("content:*", ns))
{
ReadContentRecursively(node, ns);
}
client.Close();
}
private static void ReadContentRecursively(XmlElement node, XmlNamespaceManager ns)
{
if(!string.IsNullOrEmpty(node.InnerText))
{
foreach (XmlNode innerNode in node)
{
if(innerNode is XmlText)
{
Console.WriteLine("Node " + node.Name + " with value \"" + innerNode.Value + "\"");
}
}
}
if(node.SelectNodes("content:*", ns).Count > 0)
{
foreach (XmlElement childNode in node.SelectNodes("content:*", ns))
{
Console.WriteLine("Found Field: " + childNode.Name);
ReadContentRecursively(childNode, ns);
}
}
}
Notice how ReadContentRecursively calls itself?
Hope this helps.
I am trying to hook Up a Delegate Using Reflection. This is what I have done so far
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Data;
using System.Threading;
using System.IO;
using System.Reflection;
using System.Windows;
namespace ChartHelper
{
public class ICChartHelper
{
public void RefreshChart()
{
try
{
Assembly myobj = Assembly.LoadFrom(#"C:\sample.dll");
foreach (Type mytype in myobj.GetTypes())
{
if (mytype.IsClass == true)
{
if (mytype.FullName.EndsWith("." + "ICAutomationProxy"))
{
// create an instance of the object
object ClassObj = Activator.CreateInstance(mytype);
// var eventTypes = mytype.GetEvents();
EventInfo evClick = mytype.GetEvent("OnRefreshCompleted");
Type tDelegate = evClick.EventHandlerType;
MethodInfo miHandler =
typeof(ChartHelper.ICChartHelper)
.GetMethod("RefreshApplication",
BindingFlags.NonPublic | BindingFlags.Instance);
Delegate d = Delegate.CreateDelegate(tDelegate,typeof(ChartHelper.ICChartHelper), miHandler);
MethodInfo addHandler = evClick.GetAddMethod();
Object[] addHandlerArgs = { d };
addHandler.Invoke(ClassObj, addHandlerArgs);
}
}
}
}
catch (Exception ex)
{
throw ex;
}
}
private void RefreshApplication(Object sender, EventArgs e)
{
MessageBox.Show("Bingo");
}
But in the
Delegate d = Delegate.CreateDelegate(tDelegate,typeof(ChartHelper.ICChartHelper), miHandler);
line, I am encountering the error Error binding to target method
I have also found the discusion here and tried to solve the same but with no luck.
I need help to understand what wrong I am doing?
Thanks
Your method is an instance method, so you need to use an overload of CreateDelegate which takes the target of the delegate, and pass in an instance of the declaring type. For example:
Delegate d = Delegate.CreateDelegate(tDelegate, new ICChartHelper(), miHandler);
Note that you don't need to call GetAddMethod on the EventInfo and invoke that using reflection - you can just use EventInfo.AddEventHandler.
Duplicate:
Hiding a link in asp.net
Hi
this is the cs file of the masterpage...
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
namespace LevoContactManagement
{
public partial class Default : System.Web.UI.MasterPage
{
protected void Page_Load(object sender, EventArgs e)
{
BasePage page = (BasePage)Page;
if (page.CurrentUser != null)
{
lblCurrentUser.Text = "<strong>" + page.CurrentUser.FullName + "</strong> - " + page.CurrentUser.CompanyName;
if ((Session["CCFUser"] != null) && (bool.Parse(Session["CCFUser"].ToString()) == true))
{
ctrlLinkBar.AddLink("Issues Management", "AllIssues.aspx");
}
else
{
if (true) ctrlLinkBar.AddLink("Home", "Default.aspx");
if (page.CurrentUser.Permissions.Issues()) ctrlLinkBar.AddLink("Issues Management", "AllIssues.aspx");
if (page.CurrentUser.Permissions.Time()) ctrlLinkBar.AddLink( "Time Management", "TimeEntryForm.aspx");
if (page.CurrentUser.Permissions.Time()) ctrlLinkBar.AddLink("Time Filter", "TimeFilter.aspx");
if (page.CurrentUser.Permissions.SVN() && !(this.Page is _Default)) ctrlLinkBar.AddLink("SVN", "SVN.aspx");
if (true) ctrlLinkBar.AddLink("Profile", "ChangePassword.aspx");
if (page.CurrentUser.Permissions.Administration()) ctrlLinkBar.AddLink( "Administration", "Administration.aspx");
}
}
else lnkLogout.Visible = false;
}
protected void lnkLogout_Click(object sender, EventArgs e)
{
Session.Abandon();
FormsAuthentication.SignOut();
Response.Redirect("Login.aspx");
}
}
}
i need to make the link Time Filter hidden.
the cs file of LinkBar is
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebControlLib
{
[ToolboxData("<{0}:LinkBar runat=server></{0}:LinkBar>")]
public class LinkBar : WebControl
{
struct Link
{
public string Title;
public string URL;
public override string ToString()
{
return "<a href='" + URL + "'>" + Title + "</a>";
}
}
private bool m_bIsVertical = false;
private List<Link> m_Links = new List<Link>();
public bool IsVertical
{
get
{
return m_bIsVertical;
}
set
{
m_bIsVertical = value;
}
}
public void Clear()
{
m_Links.Clear();
}
public void AddLink(string Title, string URL)
{
Link lnk = new Link();
lnk.Title = Title;
lnk.URL = URL;
m_Links.Add(lnk);
}
protected override void RenderContents(HtmlTextWriter output)
{
List<string> items = new List<string>();
foreach (Link lnk in m_Links)
items.Add(lnk.ToString());
string sep = IsVertical ? "</td></tr><tr><td>" : " | ";
output.Write(
#"
<table width='100%' class='linkBar'>
<tr>
<td>" + string.Join(sep, items.ToArray()) + #"</td>
</tr>
</table>
");
}
}
}
how do i go about it? i changed the master.designer.cs file as follows-->
public partial class Default {
protected System.Web.UI.HtmlControls.HtmlForm form1;
protected System.Web.UI.WebControls.Label lblCurrentUser;
protected System.Web.UI.WebControls.LinkButton lnkLogout;
public WebControlLib.LinkBar ctrlLinkBar;
public System.Web.UI.WebControls.ContentPlaceHolder LeftNav;
protected System.Web.UI.WebControls.ContentPlaceHolder ContentPlaceHolder1;
protected System.Web.UI.WebControls.ContentPlaceHolder BodyContent;
}
but the link still does not appear on the Design view of the masterpage, hence i cant find the id, therefore i cant hide it. What is an alternative to this?
I assume that you're talking about hiding the link to TimeEntryForm.aspx, and that you probably want to do this in only limited circumstances (which is why you don't want to just omit the line).
The link isn't actually in itself a control, so it won't have its own ID. It's a member of the List of links that belongs to the LinkBar control, and the LinkBar takes care of rendering them to the screen.
As you're adding these links to the LinkBar at run time, they won't display in the design view preview in Visual Studio - it will only display when you view the page in a browser.
I'd suggest that you get rid of the LinkBar, and just add the controls to the page as simple HyperLink controls. If you like, do this in the designer. Then you can set the visibility of each link in the code behind using the Visible property on those hyperlinks, like such:
hlTimeLink.Visible = page.CurrentUser.Permissions.Time();