📄 tabcontainerdesigner.cs
字号:
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2116:AptcaMethodsShouldOnlyCallAptcaMethods", Justification = "Security handled by base class")]
private string GetTemplateContent(ITemplate template, string id)
{
DesignerPanel contentPanel = new DesignerPanel();
contentPanel.ID = id;
template.InstantiateIn(contentPanel);
IDesignerHost host = (IDesignerHost)GetService(typeof(IDesignerHost));
Debug.Assert(host != null, "Failed to get IDesignerHost?!?");
StringBuilder persistedControl = new StringBuilder(1024);
foreach (System.Web.UI.Control c in contentPanel.Controls)
{
persistedControl.Append(ControlPersister.PersistControl(c, host));
}
return persistedControl.ToString();
}
/// <summary>
/// Get the content for a given tab or header
/// </summary>
/// <param name="tab">The tab to search</param>
/// <param name="content">True for ContentTemplate, otherwise it'll do HeaderTemplate</param>
/// <returns></returns>
private string GetTabContent(TabPanel tab, bool content)
{
if (tab != null)
{
if (content && tab.ContentTemplate != null)
{
return GetTemplateContent(tab.ContentTemplate, "_content");
}
else if (!content)
{
if (tab.HeaderTemplate != null)
{
return GetTemplateContent(tab.HeaderTemplate, "_header");
}
return tab.HeaderText;
}
}
return "";
}
/// <summary>
/// Initialize the deisigner
/// </summary>
/// <param name="component"></param>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1303:DoNotPassLiteralsAsLocalizedParameters", MessageId = "System.InvalidOperationException.#ctor(System.String)", Justification="The designer is not localized")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2116:AptcaMethodsShouldOnlyCallAptcaMethods", Justification = "Security handled by base class")]
public override void Initialize(IComponent component)
{
base.Initialize(component);
SetViewFlags(ViewFlags.TemplateEditing, true);
// make sure all the tabs have IDs and they're sited.
foreach (TabPanel tp in TabContainer.Tabs)
{
if (String.IsNullOrEmpty(tp.ID))
{
throw new InvalidOperationException("TabPanels must have IDs set.");
}
}
}
/// <summary>
/// After a editable region is edited, the designer calls back with the updated markup so we can
/// stuff it into the right tab.
/// </summary>
/// <param name="region"></param>
/// <param name="content"></param>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2116:AptcaMethodsShouldOnlyCallAptcaMethods", Justification = "Security handled by base class")]
public override void SetEditableDesignerRegionContent(EditableDesignerRegion region, string content)
{
if (region == null)
{
throw new ArgumentNullException("region");
}
string regionName = region.Name;
Debug.Assert(regionName[0] == 'c' || regionName[0] == 'h', "Expected regionName to start with c or h, not " + regionName);
bool setTabContent = regionName[0] == 'c';
regionName = regionName.Substring(1);
// figure out which tab we have.
TabPanel activeTab = (TabPanel)TabContainer.FindControl(regionName);
Debug.Assert(activeTab != null, "Couldn't find tab " + regionName);
IDesignerHost host = (IDesignerHost)GetService(typeof(IDesignerHost));
Debug.Assert(host != null, "Failed to get IDesignerHost?!?");
// push the content into the right template
PersistTemplateContent(activeTab, host, content, (setTabContent ? "ContentTemplate" : "HeaderTemplate"));
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2116:AptcaMethodsShouldOnlyCallAptcaMethods", Justification = "Security handled by base class")]
private static void PersistTemplateContent(TabPanel panel, IDesignerHost host, string content, string propertyName)
{
ITemplate template = ControlParser.ParseTemplate(host, content);
PersistTemplate(panel, host, template, propertyName);
}
/// <summary>
/// Helper method to save the value of a template. This sets up all the right Undo state.
/// </summary>
/// <param name="panel"></param>
/// <param name="host"></param>
/// <param name="template"></param>
/// <param name="propertyName"></param>
private static void PersistTemplate(TabPanel panel, IDesignerHost host, ITemplate template, string propertyName)
{
PropertyDescriptor descriptor = TypeDescriptor.GetProperties(panel)[propertyName];
using (DesignerTransaction transaction = host.CreateTransaction("SetEditableDesignerRegionContent"))
{
descriptor.SetValue(panel, template);
transaction.Commit();
}
}
/// <summary>
/// Called when we get aclick on a designer region.
/// </summary>
/// <param name="e"></param>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2116:AptcaMethodsShouldOnlyCallAptcaMethods", Justification = "Security handled by base class")]
protected override void OnClick(DesignerRegionMouseEventArgs e)
{
// is it a tab?
if (e.Region != null && e.Region.Name.StartsWith("t", StringComparison.Ordinal))
{
CurrentTabID = e.Region.Name.Substring(1);
}
else if (e.Region != null && e.Region.Name == AddTabName)
{
// is it the "AddNewTab" region?
OnAddTabPanel();
}
base.OnClick(e);
}
/// <summary>
/// Add a new tab panel.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2116:AptcaMethodsShouldOnlyCallAptcaMethods", Justification = "Security handled by base class")]
private void OnAddTabPanel()
{
IDesignerHost host = (IDesignerHost)GetService(typeof(IDesignerHost));
if (host != null)
{
TabContainer tc = TabContainer;
using (DesignerTransaction dt = host.CreateTransaction("Add new TabPanel"))
{
TabPanel tp = (TabPanel)host.CreateComponent(typeof(TabPanel));
if (tp != null)
{
// set up the inital state
//
tp.ID = GetUniqueName(typeof(TabPanel), tc);
tp.HeaderText = tp.ID;
IComponentChangeService changeService = (IComponentChangeService)GetService(typeof(IComponentChangeService));
try
{
changeService.OnComponentChanging(tc, TypeDescriptor.GetProperties(tc)["Tabs"]);
tc.Tabs.Add(tp);
}
finally
{
changeService.OnComponentChanged(tc, TypeDescriptor.GetProperties(tc)["Tabs"], tc.Tabs, tc.Tabs);
}
TypeDescriptor.GetProperties(tc)["ActiveTab"].SetValue(tc, tp);
CurrentTabID = tp.ID;
}
dt.Commit();
}
}
}
/// <summary>
/// Helper to get a unique name. Since our Tabs aren't onthe designer surface,
/// INamingSurface won't do the right thing. Fortunately, it's easy.
/// </summary>
/// <returns>A unique name like "TabPanel3"</returns>
private static string GetUniqueName(Type t, System.Web.UI.Control parent)
{
string baseName = t.Name;
int count = 1;
while (parent.FindControl(baseName + count.ToString(CultureInfo.InvariantCulture)) != null)
{
count++;
}
return baseName + count.ToString(CultureInfo.InvariantCulture);
}
/// <summary>
/// Remove the active tab panel and set the active tab to be the previous one.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification="Called via reflection")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2116:AptcaMethodsShouldOnlyCallAptcaMethods", Justification = "Security handled by base class")]
private void OnRemoveTabPanel()
{
TabContainer tc = TabContainer;
if (tc.ActiveTab != null)
{
int oldIndex = tc.ActiveTabIndex;
IDesignerHost host = (IDesignerHost)GetService(typeof(IDesignerHost));
if (host != null)
{
using (DesignerTransaction dt = host.CreateTransaction("Remove TabPanel"))
{
TabPanel activeTab = tc.ActiveTab;
IComponentChangeService changeService = (IComponentChangeService)GetService(typeof(IComponentChangeService));
try
{
changeService.OnComponentChanging(tc, TypeDescriptor.GetProperties(tc)["Tabs"]);
tc.Tabs.Remove(activeTab);
}
finally
{
changeService.OnComponentChanged(tc, TypeDescriptor.GetProperties(tc)["Tabs"], tc.Tabs, tc.Tabs);
}
activeTab.Dispose();
if (tc.Tabs.Count > 0)
{
TypeDescriptor.GetProperties(tc)["ActiveTabIndex"].SetValue(tc, Math.Min(oldIndex, tc.Tabs.Count - 1));
}
UpdateDesignTimeHtml();
dt.Commit();
}
}
}
}
/// <summary>
/// Manages our designer verbs
/// </summary>
private class TabContainerDesignerActionList : DesignerActionList
{
private TabContainerDesigner _designer;
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2116:AptcaMethodsShouldOnlyCallAptcaMethods", Justification = "Security handled by base class")]
public TabContainerDesignerActionList(TabContainerDesigner designer)
: base(designer.Component)
{
_designer = designer;
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2116:AptcaMethodsShouldOnlyCallAptcaMethods", Justification = "Security handled by base class")]
public override DesignerActionItemCollection GetSortedActionItems()
{
DesignerActionItemCollection items = new DesignerActionItemCollection();
DesignerActionMethodItem addItem = new DesignerActionMethodItem(this, "OnAddTabPanel", "Add Tab Panel", true);
DesignerActionMethodItem removeItem = new DesignerActionMethodItem(this, "OnRemoveTabPanel", "Remove Tab Panel", true);
items.Add(addItem);
items.Add(removeItem);
return items;
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Called via reflection")]
private void OnAddTabPanel()
{
_designer.OnAddTabPanel();
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Called via reflection")]
private void OnRemoveTabPanel()
{
_designer.OnRemoveTabPanel();
}
}
/// <summary>
/// a simple class to use for template instantiation
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible", Justification="Required for serialization")]
internal class DesignerPanel : System.Web.UI.WebControls.Panel, INamingContainer
{
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -