I am using Radzen Blazor Tree component in a Blazor project. By default the component comes with an event listener for single click on RadzenTreeItem. I am hoping to add functionality such that a single click on a RadzenTreeItem and a double click on a RadzenTreeItem produces different changes to the app. I am thinking of accomplishing this by using a JSInterop for the dblclick event listener, but I know this would require having individual html ids for each RadzenTreeItem and I am not sure how to go about creating unique ids for a RadzenTreeItem since the tree has a dynamic size. My question is how to create unique ids for a RadzenTreeItem if each item is being created in a RenderFragment or is there a better way to allow double click functionality?
Below is an example of the C# RenderFragment that is used to display the RadzenTreeItem:
public static RenderFragment<RadzenTreeItem> TreeDesign = (RadzenTreeItem context) => builder =>
{
builder.OpenComponent<RadzenIcon>(0);
builder.AddAttribute(1, "Icon", "crop_16_9");
builder.CloseComponent();
builder.AddContent(4, context.Text);
};
Below is an example of the html code that is calling the RenderFragment and creating the tree:
<RadzenTree Data="#entries" Change="#OnChange">
<RadzenTreeLevel Template="#TreeDesign" Text="#GetTextForNode" />
</RadzenTree>
5 months old - but I'll give you a shot on how I handle double click years ago in Silverlight.... I created an Observable that would give me an event when there were two clicks within 250MS of each other... this is called a Hot Observable in which the events simply flow by, and when a criteria matches the events, it can raise another event... I can try and dig up the code, as researching for a a double-click event and protection for blazor events.
To add perhaps a bit more clarity - this would listen to the click event you refer to, and if there were two clicks, it would invoke method A, other wise would invoke B for a single click...
A triple click would then become 1 double click, and one single click - but that would depend on the time between the first and thrid event using the Observable...
Maybe it will help someone in the future:
builder =>
{
builder.OpenComponent<RadzenIcon>(0);
builder.AddAttribute(1, "Icon", "crop_16_9");
builder.CloseComponent();
builder.OpenElement(2, "div");
builder.AddAttribute<MouseEventArgs>(3, "ondblclick", RuntimeHelpers.TypeCheck<EventCallback<MouseEventArgs>>(EventCallback.Factory.Create<MouseEventArgs>(this,
(args) => OnDoubleClick(args, context)
)));
builder.AddContent(10, context.Text);
builder.CloseElement();
};
};
private void OnDoubleClick(MouseEventArgs args, RadzenTreeItem item)
{
//
}
Related
I am implementing a category mapper. There are 2 TreeViews. Both contain categories from different sources. (Even they look like from the same source)
The user should be able to map ONE category from the left to multiple of the right treeview. This gets stored in a config file.
However, when the view is initially loaded and the user clicks on a category on the left, I want to preselect the mapped categories on the right, loaded from the config file.
I saw that I can do this with ONE selection, but I don't see an option to do this for multiple ones.
How can I achive this?
Here a ootb running demo implementation
I went through your gist and it seemed that the problem was binding selections right? I did some light digging and found that binding observable lists isn't easy. I don't think I even saw a solution that wasn't just adding listeners to mock a binding. However, wrapping that list in a SimpleListProperty seemed to do the trick. Here's a demo:
class TestView : View() {
// This mocks your target list in the ViewModel
val targetList = SimpleListProperty(listOf<String>().asObservable())
override val root = vbox(10) {
// Both table views and tree views use an Observable Selection list
listview(listOf("asefas", "asefasef", "asefasefasefase").asObservable()) {
// Wrap in SimpleListProperty, then bind
targetList.bind(SimpleListProperty(selectionModel.selectedItems))
selectionModel.selectionMode = SelectionMode.MULTIPLE
}
setPrefSize(300.0, 300.0)
}
init {
// Target list now reflects changes made to selection model
targetList.addListener { _, _, change ->
println("Selections changed to: $change")
}
}
}
I'm currently using A-Frame to build WebXR (WebVR) applications, and
it's not always that I'm able to have the controllers (Oculus Touch, Vive Controls) with me to test them out. Is there a way to "simulate" the events that the different controllers emit?
I'm not sure about lower levels, but i have an idea on a higher one:
If you have your vive controllers, and want to test out oculus touch events, you could do some mapping.
I'd do a component, intercepting the original events, and emitting new ones with the same details:
AFRAME.registerComponent("event-mapper", {
init: function() {
let viveEvents = ["menuup", "menudown"]
let oculusEvents = ["gripdown", "gripup"]
viveEvents .forEach((event, index) => {
this.el.addEventListener(event, (e) => {
this.el.emit(oculusEvents [index], {detail: e})
})
})
}
}
If you want it to be "dynamic" you could use a real Map() instead of two arrays, but here it seems redundant.
Furthermore, by including the detail in the emitted event, all details, values, targets also get passed with the new event.
So when you want your entity to react to the mapped events, you can just do:
<a-entity event-mapper></a-entity>
Check it out in my fiddle (mapped some mouse events, onto made up ones)
I'm building a calendar-based web app with fullcalendar, which is for college students to use. There are some categories I've defined. e.g, sport, art, mind, etc... every event in the fullcalendar would be assigned to a category.
What i want to do is: there're some checkboxes corresponding categories on the top of the calendar, and the user can check or uncheck some checkboxed to hide/show the related events
how would I achieve this?
One way is to put appropriate classes on each event by setting the 'className' property on the event objects you're sending to the calendar and use jquery to hide those events (e.g. $(.myClassName).hide()) when they check the checkboxes. The trouble is the events would vanish leaving a gap where they were which might not be what you want.
A better way would be to add a filter function to the events option when you first call fullCalendar like this:
fullCalendar({
...
events: {
url: ....,
success: function(events) {
$.map(events, function (e) {
if (userHasFilteredOut(e))
return null;
else
return e;
});
},
...
});
This will filter out the events before they are displayed. The function userHasFilteredOut returns true if the event object passed in is of a class the user's checkbox values indicate is filtered out. When the user checks or unchecks a checkbox, you will need to refetch all the events from the server. You need to do this:
$('#mycal').fullCalendar('refetchEvents');
Having tried a number of different solutions I keep coming back to this. I need a Window.ShowDialog, using the ViewModelLocator class as a factory via a UnityContainer.
Basically I have a View(and ViewModel) which on a button press on the the view needs to create a dialog (taking a couple of parameters in its constructor) that will process some logic and eventally return a result to the caller (along with the results of all the logic it computed).
Maybe I'm wrong for stilll looking at this from a Windows Forms perspective, but I know exactly what I want to do and I want to ideally do it using WPF and MVVM. I'm trying to make this work for a project, and ultimately don't want to have to go back to vanilla WPF in order to make it work.
I break the rules to implement a dialogwindow but tried to reduce it to a minimum. I have a method OpenDialog in my BaseViewModel:
public void OpenDialog(DialogViewModel model)
{
this.MessengerInstance.Send<DialogViewModel, MainWindow>(model);
}
And in my MainWindow:
Messenger.Default.Register<DialogViewModel>(this, model =>
{
// Instantiate the dialog box
var dlg = new DialogWindow();
// Configure the dialog box
dlg.Owner = this;
dlg.Content = model;
// Open the dialog box modally
dlg.ShowDialog();
});
That way i only have a loose coupling between my viewmodel and my MainView.
You can do the same for closing, my BaseDialogViewModel has a method:
public void CloseDialog()
{
this.MessengerInstance.Send<PopUpAction, DialogWindow>(PopUpAction.Close);
}
(PopupAction is just an enum) and my DialogWindow registers for that:
Messenger.Default.Register<PopUpAction>(this, action =>
{
switch (action)
{
case PopUpAction.Close:
this.Close();
break;
}
});
You could also leave the receiver away when sending, to keep the view class out of the viewmodel but either way i think it's a acceptable solution :)
You can do that. Just create an instance of a page/usercontrol/window and call instance.ShowDialog().
Here's my T4 templates to generate a view/viewmodel with the messaging for closing a window and other tricks.
I am using a Tree control with an XMLListContainer dataProvider.... I use an itemOpen event with the following code to update another data provider when a tree folder is opened (using small triangle) - the data provider contains all the <slide /> elements in that particular tree folder...
private function itemOpenEvent(event:TreeEvent):void {
slideDP = new XMLListCollection(event.item.elements("slide"));
slideDP.refresh();
}
If a second folder is opened thumbDP updates fine but when the first folder (or another closed folder) is clicked I want the same behaviour to happen (currently you have to close and reopen the first folder)
So I use a itemClick event - but this fires a ListEvent and I can't work out how to get the child elements from the XMLListContainer as easy... The code below throws an out of bounds exception
private function itemClickEvent(event:ListEvent):void {
treeFeed.getItemAt(event.rowIndex);
}
Can anyone help? Thanks :)
I would change your event listener to listen for a change Event, and use the selectedItem property of the Tree:
private function changeHandler(event:ListEvent):void
{
slideDP = new XMLListCollection(tree.selectedItem.elements("slide"));
slideDP.refresh();
}
You may need to cast selectedItem as XML or XMLList.