MarkupControlContainer

Ahoj. Mam dotaz ohledne spravneho uziti MarkupControlContainer
Dotvvm 4 last…

mam vlastni controlku

public class DynamicComponent : HtmlGenericControl ...

nabinduju do ni control propertu ControlName = cc:MyControl…

protected override void OnLoad(IDotvvmRequestContext context)
{....
var child = new MarkupControlContainer("cc:MyControl", c => {
    c.SetValue(MyControl.NameProperty, someValue); 
    ...
});
this.Children.Add(child);
base.OnLoad(context);
}

pekne vse vykresli, ale

do cc:MyControl pridam button s eventem Click a commandem controlky cc:MyControl…

neco jako:

<dot:LinkButton Click="{command: _control.DoAdd()}">ADD</dot:LinkButton>

samotna kontrolka funguje

pri vygenerovani pres MarkupControlContainer a klik na button ADD
skonci chybou… neco jako

Napada vas neco? Diky

{
“Error”: {
“FileName”: null, “Msg”: “Multiple controls with the same UniqueID ‘c246_c53_c9a0’ were found: \n * <dot: MarkupControlContainer /> from Views/App/Sandbox/DashboardDynamicTest.dothtml: 13\n * <: DashDokladLastUsed /> from C: \Workfiles\Web\TestApp.Dotvvm4\TestApp.App\Controls/Dashboard/DashboardModule\DashDokladLastUsed.dotcontrol", “RelatedProperty”: null, “RelatedBinding”: null, “RelatedResolvedControl”: null, “RelatedDothtmlNode”: null, “RelatedResource”: null, “RelatedControl”: {
“Control”: “MarkupControlContainer”, “Properties”: {
“Internal.UniqueID”: “c9a0”
}
, “LifecycleRequirements”:“PreInit, Init, Load, PreRender”
}
, “Location”:null, “Message”:"Multiple controls with the same UniqueID ‘c246_c53_c9a0’ were found:\n * <dot:MarkupControlContainer /> from Views/App/Sandbox/DashboardDynamicTest.dothtml:13\n * <
:DashDokladLastUsed /> from C:\Workfiles\Web\TestApp.Dotvvm4\TestApp.App\Controls/Dashboard/DashboardModule\DashDokladLastUsed.dotcontrol”, “Data”: {
}
, “InnerException”:null, “HelpLink”:null, “Source”:“DotVVM.Framework”, “HResult”:-2146233088, “StackTrace”:" at DotVVM.Framework.Controls.DotvvmControl.FindControlByUniqueId(String controlUniqueId) in //src/Framework/Framework/Controls/DotvvmControl.cs:line 440\r\n at DotVVM.Framework.ViewModel.Serialization.DefaultViewModelSerializer.ResolveCommand(IDotvvmRequestContext context, DotvvmView view) in //src/Framework/Framework/ViewModel/Serialization/DefaultViewModelSerializer.cs:line 375\r\n at DotVVM.Framework.Hosting.DotvvmPresenter.ProcessRequestCore(IDotvvmRequestContext context) in /_/src/Framework/Framework/Hosting/DotvvmPresenter.cs:line 236"
}
, “TraceID”:“0HN6767JTVNC7:00000002”, “URL”:“http://localhost:34147/App/sandbox/dashboarddynamictest”, “StackTrace”:null, “LineNumber”:null, “FileName”:null, “Procedure”:null
}

Takto z hlavy nevím co je tam blbě. Každopádně jde o to, že na to aby se dohledalo kam command patří musí mít markup controlky jedinečná interní IDčka.

To IDčko je složeno z komponent většinou přiřazených při kompilaci (to jsou ty cČÍSLO), a případně pak dodělávaných když přidá novou komponentu bez IDčka do DotvvmControlCollection. Ve vašem případě to tedy vypadá, že už ta DynamicComponent nemá unikátní IDčko. Můžete to zkusit trochu podebugovat, k těm IDčkům se dostanete pomocí metody GetDotvvmUniqueId na té controlce. Svůj fragment má každá controlka uložený v dotvvm property Internal.UniqueIDProperty. Můžete ho zkusit i změnit na něco vlastního, v takovém případě doporučuji vzít Internal.UniqueIDProperty té DynamicControl a přilepit k němu nějaký další string.

Super, diky za rychlou reakci. Vyresil jsem to tak, ze jsem DynamicComponent prepsal na CompositeControl a tam se napocitaly UniqueID asi dobre :slight_smile:

jak budu u kodu poslu priklad pro dalsi cleny. Pekny den :+1:

1 Like

Takto je to fajn…

public class DynamicComponent : CompositeControl
{

public IEnumerable<DotvvmControl> GetContents(
    ValueOrBinding<DynamicControlItem> controlItem
    )
{
    var x = this.GetValue(DotVVM.Framework.Controls.Internal.UniqueIDProperty);
    var controlNo = x + this.Children.Count().ToString();

    // Pokud je controlItem hodnota, můžeme ji získat přímo
    string controlItemName; //= "dash:DashDokladLastUsed"
    if (controlItem.HasValue)
    {
        controlItemName = controlItem.ValueOrDefault.ControlName;
    }
    else
    {
        // Pokud je controlItem binding, vyhodnotíme ho
        //var context = new DotvvmBindingContext(); // Kontext, který bude třeba pro vyhodnocení výrazu
        var dynamicItem = controlItem.Evaluate(this);

        // Získáme hodnotu vlastnosti Nazev
        controlItemName = dynamicItem.ControlName;
    }

    var dynamicCtrl = new MarkupControlContainer(controlItemName, c =>
    {
        var thisDC = this.GetValueBinding(DotvvmBindableObject.DataContextProperty);
        c.SetProperty(DotvvmBindableObject.DataContextProperty, thisDC!);
        c.SetProperty(DotVVM.Framework.Controls.Internal.UniqueIDProperty, controlNo);
    });

    dynamicCtrl.Parent = this.Parent;
    dynamicCtrl.ClientIDMode = ClientIDMode.AutoGenerated;            

    yield return dynamicCtrl;


}