Is there a way to add some tabs inside Composite C1 function? - c#

I'm using the 6th version of Composite c1 CMS. And i'm wondering about is there a way to add some kind of tabs inside Composite functions? For example, i have a function
`public override string MyFunction
{
get { return "SomeFunction"; }
}
[FunctionParameter(DefaultValue = "Nad")]
public string Name { get; set; }
[FunctionParameter(Label = "Another Field", DefaultValue = "", HideInSimpleView = true)]
public string AnotherField { get; set; }
[FunctionParameter(Label = "Some URL", DefaultValue = "", HideInSimpleView = true)]
public string Url { get; set; }`
and i want to add some kind of tabs, that user should interact with only if, for example, function name is "someName". Is there a way to a)add that kind of tabs,so user could switch between the main tab and the other one; and b)conditionally show this tabs?

No, unlike data forms, where the layout can be defined with an xml file, such functionality isn't implemented for function calls, when one only can define widgets for function parameters but not the overall layout.
It is possible to replace the default function call editor with a custom page, like it is done in the FormBuilder package.
http://docs.c1.orckestra.com/Console/Custom-Function-Call-Editor
The available example is based on WebForms, so it may not be straightforward to implement.
http://docs.c1.orckestra.com/Console/Custom-Function-Call-Editor/Web-Form

Related

Backendless c# desktop application saving data but by empty or null values

I have a desktop app written in c# and I added app id and key id
and used this code to add data to database but the data is always empty or null.
var film = new Film();
film.setName(“soooft”);
film.setGenre(“aaa”);
film.setPlot(“fdgveqw”);
film.setUrl(“gdfwrw”);
var f = Backendless.Data.Of<Film>().Save(film);
I googled Backendless and it's a third-party solution. (See https://github.com/Backendless/.NET-SDK)
Usage gets explained at https://backendless.com/docs/dotnet/data_data_object.html
But I'm suspicious about why you use setName(), setGenre(), setPlot and setUrl in your code. Seems your Film class is missing properties. I would expect you'd be writing this instead:
var film = new Film();
film.Name = “soooft”;
film.Genre = “aaa”;
film.Plot = “fdgveqw”;
film.Url = “gdfwrw”;
But that would mean those fields are declared as public properties in your class like this:
public class Film
{
public string Name { get; set; }
public string Genre { get; set; }
public string Plot { get; set; }
public string Url { get; set; }
}
So I don't know why you have those setName and other methods. The Backendless API specifies that these fields need to be public properties so it can read them through reflection. Your code seems to suggests that they're not proper properties as indicated by their example and my code of the Film() class.
Make sure to use public get/set properties instead of private fields and the data will be saved properly.

Automagically handling multi-lingual properties in a .NET class

I am trying to handle multiple languages in an ASP.NET Webforms (.NET 4.5, C#) application of mine.
Basically, some of my entities in my SQL Server 2012 database have properties like Name or Description which exist in three languages - German, French, Italian.
Those are stored as columns Name_De (German), Name_Fr (French), and Name_It (Italian).
When I create my .NET objects from the database, of course, I also get those three properties in my entity class. But for displaying on screen, in a grid for instance, it would be nice if I could somehow "magically" always show the "right" language. This should be based on the Thread.Current.CurrentUICulture.TwoLetterISOLanguageName (which returns de, fr or it, depending on the browser's language preferences).
So I was hoping to somehow be able to create e.g. a .NET attribute that would allow me to do something like this:
Base "Module" entity - generated from existing SQL Server database:
public partial class Module
{
public string ModuleCode { get; set; }
public string Name_De { get; set; }
public string Name_Fr { get; set; }
public string Name_It { get; set; }
... // other properties
}
Partial extension in a separate file
public partial class Module
{
[Multilingual]
public string Name { get; set; }
}
The base idea is: I can access the Module.Name property, and depending on the current setting of CurrentUICulture, either the value of Name_De, Name_Fr or Name_It would be fetched, when I access the getter of the Name property.
Can something like this be done in C# ? I have looked at a lot of custom attribute implementations, but nothing ever seemed to be doing something like this...
Assuming you are using two separate entities (one generated by your SQL entities and one "business entity" which only contains a Name property), are you open to using something like AutoMapper ?
If you are, then you could tweak your resolve function to map the entity depending on the current thread culture.
switch(Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName.ToUpperInvariant())
{
case "DE":
return dto.Name_De;
case "FR":
return dto.Name_Fr;
// ...
default :
return String.Empty;
}
which would work for your scenario.
If this is a solution that could work for you, I think this question is very close to what you're looking for : Automapper Mapping for Localization Resolver in a Multi-Language Website
If you do go down the custom attribute route, you will have to deal with Reflection stuff and string parsing I'm afraid. AFAIK, there is no built in way to do this with the localization functions provided by .NET. AutoMapper will hide that from you.
The problem with custom attributes in this case is that you are still trying to access the Name property. You are trying to "shadow" the default behaviour of the property by making it access other properties. If I understand correctly you want the Multilingual custom attribute to turn your property into :
public String Name
{
get
{ switch(Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName.ToUpperInvariant())
{
case "DE":
return dto.Name_De;
case "FR":
return dto.Name_Fr;
// ...
default :
return String.Empty;
}
}
}
If that's correct, then you won't be able to do that easily with attributes, simply because the attribute will never be aware of the existence of the Name_De property.
Other option that still isn't quite what you're looking for :
void Main()
{
Module mod = new Module();
mod.Name_De = "name";
mod.Name_Fr = "nom";
// This is the unfortunate nasty bit. I address the property using its name
// in a String which is just bad. I don't think there is a way
// you will be able to address the ".Name" property directly and have
// it return the localized value through your custom attribute though
String localizedValue = mod.GetLocalizedProperty("Name");
}
[AttributeUsage(AttributeTargets.Property)]
public sealed class MultilingualAttribute : Attribute
{
public MultilingualAttribute()
{
}
}
public static class ModuleExtensions
{
public static String GetLocalizedProperty(this Module module, String propName)
{
var type = typeof(Module);
var propInfo = type.GetProperty(propName);
// Make sure the prop really is "Multilingual"
if(Attribute.IsDefined(propInfo, typeof(MultilingualAttribute)))
{
String localizedPropName = propInfo.Name;
switch(Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName.ToUpperInvariant())
{
case "DE":
localizedPropName += "_De";
return type.GetProperty(localizedPropName).GetValue(module, null).ToString();
case "FR":
localizedPropName += "_Fr";
return type.GetProperty(localizedPropName).GetValue(module, null).ToString();
}
}
return String.Empty;
}
}
public class Module
{
public String Name_De {get; set;}
public String Name_Fr {get; set;}
[Multilingual]
public String Name {get; set;}
public Module()
{
}
}
I don't know of a more powerful way to use custom attributes for what you're looking for unfortunately. Quite frankly, I don't think this is a good solution, only posted because I was trying to see what I could do with custom attributes. There is no real point in using this code over a more "normal" property which would do the same thing in a clearer way (without attributes). As you say in your original question, your goal is to intercept the call to the Name property and this doesn't achieve it.

How to conditionally show/hide properties of a page in EPiServer 9 CMS admin/backend

I have spent a few days banging my head on this one. There does not seem to be very many examples or resources online so I am hoping someone in the community can assist me.
I have a Page in EPiServer that has an int property that is tagged as a SelectOne (a drop down list). I need to conditionally show/hide another property of the page type. I came across this example online. I can get it to work as written, but the second I try to modify it (with my very limited knowledge) it ceases to work.
This is my Page in EPiServer:
//'SitePageData' extends page data but is prolly irrelevant to this question
[ContentType]
public class LocationPage : SitePageData
{
[CultureSpecific]
[Display(
Name = "Location Type",
Description = "",
GroupName = SystemTabNames.Content,
Order = 10)]
[SelectOne(SelectionFactoryType=typeof(LocationTypeSelectionFactory))]
[UIHint("LocationType")]
public virtual int LocationType { get; set; }
[CultureSpecific]
[Display(
Name = "Address Key",
Description = "",
GroupName = SystemTabNames.Content,
Order = 20)]
public virtual string AddressKey { get; set; }
//........Rest of class properties here.......
}
This is my Editor Descriptor:
[EditorDescriptorRegistration(TargetType=typeof(string), UIHint="LocationType")]
public class LocationTypeEditorDescriptor : EditorDescriptor
{
public override void ModifyMetadata(EPiServer.Shell.ObjectEditing.ExtendedMetadata metadata, IEnumerable<Attribute> attributes)
{
ClientEditingClass = "alloy/LocationType";
base.ModifyMetadata(metadata, attributes);
}
}
This is my JS file (LocationType.js) located in the /ClientResources/Scripts/ folder
define([
"dojo/_base/declare",
"dojo/_base/lang",
"epi/shell/layout/SimpleContainer"
],
function (
declare,
lang,
SimpleContainer
) {
return declare([SimpleContainer], {
addChild: function (child) {
// Summar: Add a widget to the container
this.inherited(arguments);
if (child.name.indexOf("locationtype") >= 0) {
this.own(child.on("change", lang.hitch(this, this._updateDropdown)));
},
_updateDropdown: function (obj) {
console.log(obj.value);
}
}
});
});
As you can see I am just trying to register an on change event (like in the linked example above). I assume this is the key functionality I would need to then selectively hide the "AddressKey" field. As you can see I haven't tackled the first problem yet.
I think one of my problems is I am potentially extending the wrong container type in dojo. I don't know enough to know for sure however.
Has anyone implemented a similar functionality in EPiServer? Is this just a super simple Dojo question?
I appreciate any and all help, thanks in advance !

With Asp.Net Mvc programmatically define section name in content page

I'm not talking about the RenderSection and my question is not related direcly with layout page.
First of all i want to tell you what im trying to do. I have a
public class Module
{
public int Id { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int Ordering { get; set; }
public string Position { get; set; }
public bool Published { get; set; }
public string ModulePath { get; set; }
public bool ShowTitle { get; set; }
}
table named Module. Modules are like Widgets. Please pay attention to the Position and ModulePath fields.
Positions are like ContentPlaceHolder defined in Layout page. In Mvc i define position like below.
RenderSection("PositionName", required:false)
ModulePath field holds the PartialView's location. They will be rendered in layout.
Problem starts here. How to do this programmatically.
Normally we use;
#section PositionName
{
#html.Partial(...)
}
to define a section in content page.
In Asp.net WebForms it is very easy to do.
ContentPlaceHolder.FindControl(PositionName).Controls.Add(..)
I need to specify section names programmatically, which is in a content page
Actually i need something like this;
foreach(var item in Model.Modules)
{
this.AddSection(item.Position, item.ModulePath, item.Ordering)
}
Manual way
#section PositionName
{
#html.Partial("~/Views/Shared/AModule.cshtml")
#html.Partial("~/Views/Shared/AnotherModule.cshtml")
#html.Partial("~/Views/Shared/AnotherModule.cshtml")
}
I tried;
#section #SectionName
{
...
}
ofcource failed.
So its very good idea to dynamically place PartialViews anywhere of page which their positions setted at administration panel. Thats what im trying to do.
From my knowledge there's no option to do this within ASP.NET MVC, but it should be do-able.
As pages are rendered into HTML they get added to the ViewContext object, so I imagine you'd want to replace areas of the HTML with your rendered view. You can access the current rendered HTML as a string like so:
var htmlContent = string.Empty;
var view = ViewEngines.Engines.FindView(ControllerContext, relativePath, null);
using (var writer = new StringWriter())
{
var context = new ViewContext(ControllerContext, view.View, ViewData, TempData, writer);
view.View.Render(context, writer);
writer.Flush();
htmlContent = writer.ToString();
}
With this in mind you could programatically replace areas of the string by using some kind of tag that you could match against.
You can define a section programmatically like this:
DefineSection("YoursectionName", async (a) =>
{
this.Write(await this.Component.InvokeAsync(widget.Name, widget.Parameters));
});
Essentially, you would do a Select over all the sections and define the section for each by invoking the given component and then writing the resulting HTML.
There's no way to dynamically add a section, but you can dynamically render things within an existing section. For example:
#section FooPosition
{
foreach (var module in models.Where(m => m.Position == "FooPosition"))
{
#Html.Partial(...);
}
}
In other words, you define sections for the available positions, and then allow the module to have only one of those available positions. Then, you just render whatever modules belong to that position inside the section.

make a structure for generating custom form

I am developing a learning management system with asp.net c#
now i want to make a structure for generating university forms , but these forms may change in future or need new forms , i want make a structure for admin of website to generate custom forms without coding, admin only add the name of feilds and type of that ( its text box or checkbox and ... ) , then it should be a printable from , also admin can add explanation in diffrent part of the form...
i dont know how should i do this ?
is there any API or some idea ?
You could make some clases for your form controls like: InputBox, TextBox, CheckBox, RadioButton. Then a form class could contain lists of your input controls.
class FormInputControl
{
public string Description { get; set; } //Every form input has a description like User, link, what you want that form input control instance to describe
public abstract object Value { get; set; }
}
class InputBox : FormInputControl
{
public string Text { get; set; }
public overwrite object Value
{
get { return Text; }
set { Text = value as string; }
}
}
class Form
{
public IList<FormInputControls> { get; set; }
}

Categories