So I am trying to display a navigational pane vertically using blazor and devexpress controls , the devexpress controls Form Layout already does the resizing and changes the navs orientation from horizontal to vertical, however i cannot get the vertical navigation to be hidden using a button click. Note I cannot use any plugins due to copyright's etc... if anyone can assist thank you in advance!
Here is an example on how to hide a component on button click. Your dev express control can go in where ShowHideComponent is.
Main Component:
#page "/test"
<button #onclick="(() => ShowComponent = true)">Show</button>
<button #onclick="(() => ShowComponent = false)">Hide</button>
#if (ShowComponent)
{
<ShowHideComponent></ShowHideComponent>
}
#code {
bool ShowComponent { get; set; } = false;
}
ShowHideComponent.razor:
<div>Show Or Hide This</div>
Related
Is it possible to cache the output of a RenderFragment in Blazor WebAssembly?
Specifically, this is to retain components shown intermittently without rendering them to the browser. With "rendering to the browser" here I mean outputting HTML to the browser.
I am trying to get this to work to improve performance in a library I am writing where two-dimensional data is shown in the browser. The resulting grid is virtualized to prevent having tens of thousands of elements in the DOM since having that many elements results in a degraded experience.
When virtualizing, elements outside the view are not rendered only to be rendered when they shift into view.
The caching mechanism should preserve the HTML output of Razor Components such that the components can be removed from and added to the DOM without having to be reinitialized and rerendered.
Currently, I have not found a way to achieve this.
A basic set-up to reproduce what I have tried so far is as follows:
create a Blazor WebAssembly project using the default template without hosting.
Add a Razor Component with the name ConsoleWriter.razor to Shared and set the contents as follows:
<h3>ConsoleWriter #Name</h3>
#code {
[Parameter]
public string? Name { get; set; }
protected override void OnInitialized() {
Console.WriteLine($"ConsoleWriter {this.Name} initialized");
}
protected override void OnAfterRender(bool firstRender) {
if(firstRender) {
Console.WriteLine($"ConsoleWriter {this.Name} rendered");
} else {
Console.WriteLine($"ConsoleWriter {this.Name} re-rendered");
}
}
// Trying to stop rerendering with ShouldRender.
// Does not stop the rendering in scenario's where the component has just been initialized.
protected override bool ShouldRender() => false;
}
Replace the contents of Index.razor with the following code:
#page "/"
<p>Components are showing: #showComponents</p>
<button #onclick="() => this.showComponents=!this.showComponents">Toggle</button>
#* Here the components are in the DOM but can be hidden from view, still bogging down the DOM if there are too many. *#
<div style="#(this.showComponents ? null : "display:none;")">
<ConsoleWriter Name="OnlyHidden" /> #* Does not intialize or rerender when showComponents is toggled *#
</div>
#* Here the components are not in the DOM at all when hidden, which is the intended scenario but this initializes the components every time they are shown. *#
#if(this.showComponents) {
<ConsoleWriter Name="Default" /> #* Intializes and rerenders when showComponents is toggled *#
#consoleWriter #* Intializes and rerenders when showComponents is toggled *#
<ConsoleWriter #key="consoleWriterKey" Name="WithKey" /> #* Intializes and rerenders when showComponents is toggled *#
}
#code {
private bool showComponents = false;
private object consoleWriterKey = new object();
private RenderFragment consoleWriter { get; } = builder => {
builder.OpenComponent<ConsoleWriter>(0);
builder.AddAttribute(1, nameof(ConsoleWriter.Name), "RenderFragment");
builder.CloseComponent();
};
}
When running the project and checking the browser console, you can see which components report being reinitialized or rerendered.
The components can be toggled by clicking the button.
Unfortunately, all of those being removed from and added to the DOM report back whenever being toggled to be shown despite their content never changing.
Does anyone have another idea how to approach this?
I just want to load a razor component into another razor component when user click search button then I want to show search razor component (page) into a hidden div when the user click hide button then it will be hidden. like inline popup.
Like this:
Main Component:
#page "/test"
<button #onclick="(() => ShowComponent = true)">Show</button>
<button #onclick="(() => ShowComponent = false)">Hide</button>
#if (ShowComponent)
{
<ShowHideComponent></ShowHideComponent>
}
#code {
bool ShowComponent { get; set; } = false;
}
ShowHideComponent.razor:
<div>Show Or Hide This</div>
I'm attempting to create a user control that houses a tab control.
My question is, how do I expose the tab control through the user control so we can add tabs?
The entire control will house three areas: command buttons at the top, the tab control, and a styled textblock that displays messages.
The command buttons will be configurable as dependencyproperties, so we may choose to show the apply button or not when we use the usercontrol. I'm strictly a designer and not a developer, so I'm trying to get my feet wet in building this control, but I'm in a little over my head.
I have no problem whipping up the XAML for what I'm trying to accomplish, just having a hard time making it reusable.
More details on what I have tried so far (haven't tried anything in the answers just yet).
I attempted to add a dependencyproperty that would expose the collection for the tabcontrol itemssource:
public IEnumerable<object> TabSource
{
get { return (IEnumerable<object>)GetValue(TabSourceProperty); }
set { base.SetValue(FunctionPanel.TabSourceProperty, value); }
}
public static DependencyProperty TabSourceProperty = DependencyProperty.Register(
"TabSource",
typeof(IEnumerable<object>),
typeof(FunctionPanel));
And then bind to it in the user control XAML:
<TabControl Grid.Row="1" ItemsSource="{Binding TabSource}" />
Finally, I would like to use it in the window XAML like so:
<local:FunctionPanel>
<local:FunctionPanel.TabSource>
<TabItem Header="Test" />
</local:FunctionPanel.TabSource>
</local:FunctionPanel>
But this returns TabSource is unrecognizable or unaccessible. I will attempt the solutions provided below.
My question is, how do I expose the tab control through the user control so we can add tabs?
One straight forward option would be adding a public method to the user control:
public void AddTab(string header)
{
this.tabControl.Items.Add(header);
}
another option would be to expose the Items property on the user control:
public ItemCollection Items
{
get { return this.tabControl.Items; }
}
I provide you with a sample to open a Page inside a Tab Control , hope it helps :
public void OpenTabForm(Page oPage)
{
try
{
Frame oFrame = new Frame();
oFrame.Content = oPage;
TabItem myItem = new TabItem();
myItem.Header = oPage.Name; //give the header text
myItem.Content = oFrame;
tbtabMain.Items.Add(myItem);
tbtabMain.SelectedItem = myItem;
}
catch (Exception ex)
{
//handle error
}
}
I am trying to use the Telerik MVC Menu control (as a button bar), but can't seem to be able to set the width to auto-generate. What I mean is, the menu continues to the end of the DIV. I would like the menu to only be as wide as the sum of the button widths. Actually, the Telerik demo is doing the same thing as my menu is doing:
http://demos.telerik.com/aspnet-mvc/razor/menu/sitemapbinding
(Look at how the menu continues on to the right of "Other product lines").
Here is my menu:
#{ Html.Telerik().Menu()
.Name("case-history-button-menu")
.ClientEvents(events => events.OnSelect("onCaseHistoryMenuBarSelect"))
.Items(menu =>
{
menu.Add()
.Text("Add a Response").HtmlAttributes(new { id = "cases-history-addresponse" } ); #*Sets the ID HTML attribute so we can access it *#
menu.Add()
.Text("Add a Comment").HtmlAttributes(new { id = "cases-history-button-addcomment" }); ;
menu.Add()
.Text("Back to Cases").HtmlAttributes(new { id = "cases-history-button-back" }); ;
})
.Render();
}
I do realize that I could just hard code my width ... but as I add or remove buttons (programatically) I want the menu to resize.
The Telerik MVC menu is rendered as an <UL> element. The latter has block display by default which means it occupies all the available space. You can override the display to "inline-block" and then the menu should be sized as you need it to:
#{ Html.Telerik().Menu()
.Name("case-history-button-menu")
// set the display to inline-block
.HtmlAttributes( new { style = "display: inline-block" } )
}
Have in mind though that older versions of IE won't accept inline-block display. You may need "inline" if you must support older IEs.
I have a few panels with different directshow IVideoWindow handles bound to them so that the videos get shown inside the panels (WindowStyle properties are: Child,ClipSiblings,ClipChildren,Caption) Now I would like to move these panels around but I can only manage to move them when the video content is not filling the entire panel and I'm clicking+holding mouse button on the empty panel space. I can move the video windows around in the panels but of course they only move inside their respective panel space.
Is there a way to bind the video window content directly to the panel , for example the entire panel with content moves freely around when I click+hold the videowindow menu bar?
Thanks in advance.
Forgot to mention,this is in c#.
I use the Video Mixing Renderer 9 and have it tied to a user control. I have set the VMR9 to Windowless mode and then set the video clipping window on the IVMRWindowlessControl9 interface to the handle of my user control. I also set the video to fill the panel completely, using IVMRWindowlessControl9.GetNativeVideoSize, IVMRWindowlessControl9.SetAspectRatioMode, and IVMRWindowlessControl9.SetVideoPosition whenever the panel gets resized. When the form that contains my user control gets moved around, the video follows along. This is all done with C# and DirectShow.NET.
Edited to add sample code:
public partial class VideoPanel : UserControl
{
private VideoMixingRenderer9 _renderer;
private IVMRWindowlessControl9 _windowlessControl;
public VideoMixingRenderer9 Renderer
{
get
{
return _renderer;
}
set
{
_renderer = value;
if (_renderer != null)
{
var filterConfig = _renderer as IVMRFilterConfig9;
if (filterConfig != null)
{
filterConfig.SetRenderingMode(VMR9Mode.Windowless);
_windowlessControl = _renderer as IVMRWindowlessControl9;
if (_windowlessControl != null)
{
_windowlessControl.SetVideoClippingWindow(Handle);
SetSize();
}
}
}
}
}
private void SetSize()
{
var srcRect = new DsRect();
var dstRect = new DsRect(ClientRectangle);
int arWidth, arHeight;
_windowlessControl.GetNativeVideoSize(out srcRect.right, out srcRect.bottom, out arWidth, out arHeight);
_windowlessControl.SetAspectRatioMode(VMR9AspectRatioMode.LetterBox);
_windowlessControl.SetVideoPosition(srcRect, dstRect);
}
}
I solved it finally and I can't believe how silly I was. I left out the
hr = videoWindow.put_MessageDrain(hWin.Handle);
line , of course the videowindow wouldnt "listen" to the panel.