I am trying to click a button with no id, only class. Because of that, I have had to recue the element by xpath, having an Element object, which no click method.
Does anyone know some strategy to achive clicking this Element?
Here the code where I am getting the Element:
WebView wv = new WebView();
WebEngine we = wv.getEngine();
we.load("https://www.milanuncios.com/");
we.getLoadWorker().stateProperty().addListener((observable, oldState, newState) -> {
if (newState == Worker.State.SUCCEEDED) {
Document doc = we.getDocument();
Element inputField = null;
try {
inputField =
(Element) XPathFactory.newInstance().newXPath().evaluate("//*[#class=\"ma-NavigationTopNav-mainActions-desktop\"]",
doc, XPathConstants.NODE);
} catch (XPathExpressionException e) {
e.printStackTrace();
}
if (inputField != null) {
LOGGER.log(Level.INFO, "DENTRO "+inputField);
}
}
});
processPaneField.getChildren().add(wv);
Finally resolved with js script:
we.executeScript("document.getElementsByClassName('ma-NavigationTopNav-mainActions-desktop')[0].click()");
Related
I am working on an App that requires one list view having text labels with NSUnderlineStyle on user deletion.
As per the requirement user have Delete/restore option in detail screen. On delete confirmation the text label should be underline style for that particular cell.
I am using LabelRenderer for NSUnderlineStyle in Xamarin iOS.
But currently ListView displays text Labels with underline style which is not deleted by user on list view scroll. The underline style are swapping from one cell label to another on list view scroll.
Below my sample code.
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (this.Control == null)
{
return;
}
if (this.Element is ExtendedLabel extended)
{
var strikethroughStyle = extended.IsStrikeThrough ? NSUnderlineStyle.Single : NSUnderlineStyle.None;
this.Control.AttributedText = new NSMutableAttributedString(
extended.Text ?? string.Empty,
this.Control.Font,
strikethroughStyle: strikethroughStyle);
}
}
This is the common issue of TableView Cell Resue , tableView will reuse the cell for the visible(inside screen shot) ones , so it would show the previous style .
To solve this we can forcedly set the style each time when the cell is going to display .
Create custom renderer for ListView , and do this in WillDisplay method ,before it we need to override TableView's Delegate.
[assembly: ExportRenderer(typeof(ListView), typeof(MyRenderer))]
namespace FormsApp.iOS
{
public class MyDelegate : UITableViewDelegate
{
List<Model> data;
public MyDelegate(List<Model> _data)
{
data = _data;
}
public override void WillDisplay(UITableView tableView, UITableViewCell cell, NSIndexPath indexPath)
{
var views = cell.ContentView.Subviews;
foreach (var view in views)
{
if(view is LabelRenderer renderer)
{
UILabel label = renderer.Control;
var strikethroughStyle = data[indexPath.Row].YourProperty?NSUnderlineStyle.Single : NSUnderlineStyle.None;
label.AttributedText = new NSMutableAttributedString(
label.Text ?? string.Empty,
label.Font,
strikethroughStyle: strikethroughStyle);
}
}
}
}
public class MyRenderer : ListViewRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<ListView> e)
{
base.OnElementChanged(e);
if (e.OldElement != null)
{
// Unsubscribe
}
if (e.NewElement != null)
{
IEnumerable<Model> data = (IEnumerable<Model>)Element.ItemsSource;
Control.Delegate = new MyDelegate(data.ToList());
}
}
}
}
I need my web view to be tappable and scrolable. Once I implement on touch the scroll doesnt work. This way i managed to get it working however now i dont know how to make the web view tappable? the ButtonPress does nothing and if i use Move then i am just scrolling
This my my render in mu droid project
class ExtendedWebViewClient : WebViewClient
{
WebView _webView;
public async override void OnPageFinished(WebView view, string url)
{
try
{
_webView = view;
if (_xwebView != null)
{
view.Settings.JavaScriptEnabled = true;
await Task.Delay(100);
string result = await _xwebView.EvaluateJavaScriptAsync("(function(){return document.body.scrollHeight;})()");
_xwebView.HeightRequest = Convert.ToDouble(result);
}
base.OnPageFinished(view, url);
}
catch (Exception ex)
{
Console.WriteLine($"{ex.Message}");
}
}
public override bool ShouldOverrideUrlLoading(Android.Webkit.WebView view, IWebResourceRequest request)
{
return true;
}
}
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
{
base.OnElementChanged(e);
_xwebView = e.NewElement as ExtendedWebView;
_webView = Control;
if (e.OldElement == null)
{
_webView.SetWebViewClient(new ExtendedWebViewClient());
}
if (e.OldElement != null)
{
Control.Touch -= ControlOnTouch;
Control.ScrollChange -= ControlOnScrollChange;
}
if (e.NewElement != null)
{
Control.Touch += ControlOnTouch;
Control.ScrollChange += ControlOnScrollChange;
}
}
private void ControlOnScrollChange(object sender, ScrollChangeEventArgs scrollChangeEventArgs)
{
if (scrollChangeEventArgs.ScrollY > 0 && scrollChangeEventArgs.OldScrollY == 0)
{
Control.Parent.RequestDisallowInterceptTouchEvent(true);
}
}
private void ControlOnTouch(object sender, Android.Views.View.TouchEventArgs e)
{
// Executing this will prevent the Scrolling to be intercepted by parent views
switch (e.Event.Action)
{
case MotionEventActions.Down:
Control.Parent.RequestDisallowInterceptTouchEvent(true);
break;
case MotionEventActions.Up:
Control.Parent.RequestDisallowInterceptTouchEvent(false);
break;
case MotionEventActions.ButtonPress:
Console.WriteLine("press");
break;
case MotionEventActions.Mask:
Console.WriteLine("mask");
break;
}
// Calling this will allow the scrolling event to be executed in the WebView
Control.OnTouchEvent(e.Event);
}
Instead of using the gesture recognizer on your webview, you can use the Focused event like following . It will been invoked when you tap the WebView .
var wb = new WebView
{
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.FillAndExpand,
Source = "xxx",
};
wb.Focused += (sender, event) =>
{
//Handle your logic here!
wb.Unfocus();
};
Unfocus() is used if you want to implement your logic everytime the webview is tapped.
after i finished slide down menu (which is a stacklayout containing buttons) on button click on my Pcl i am trying to hide this menu when the user taps any part of the page out of my menu
i used TapGestureRecongnizer and added it to content but it doesnot work on other children elements
TapGestureRecognizer ContentGesture = new TapGestureRecognizer();
ContentGesture.Tapped +=(s,o)=>{
if (CornerFrame.IsVisible == true)
{ CornerFrame.IsVisible = false; }
};
this.Content.GestureRecognizers.Add(ContentGesture);
Try this
Below code in your stack layout page
public event EventHandler<bool> ItemChanged;
TapGestureRecognizer ContentGesture = new TapGestureRecognizer();
ContentGesture.Tapped +=(s,o)=>{
ItemChanged?.Invoke(this, true);
};
this.Content.GestureRecognizers.Add(ContentGesture);
Below code in your main page where you add CornerFrame in page
CornerFrame.ItemChanged += (object sender, bool arg) =>
{
if (CornerFrame.IsVisible == true)
{ CornerFrame.IsVisible = false; }
};
I have made treeview. I want to make treeview like this.
when I enter mouse to item, that item should change image.
when I clcick mouse to item, that item should chnage image.
I know how the way getSelectionMode()... but I don't know hover event.
Please help me.
Not sure if I understand you correct.
But to change your image as soon as you click an image use a selectedItemProperty listener:
treeView.getSelectionModel().selectedItemProperty().addListener( new ChangeListener() {
#Override
public void changed(ObservableValue observable, Object oldValue,
Object newValue) {
TreeItem<String> selectedItem = (TreeItem<String>) newValue;
// do something
}
});
If you want it as soon as you hover over the item you can use a hoverProperty on the row:
treeView.setRowFactory(tableView -> {
final TableRow<Person> row = new TableRow<>();
row.hoverProperty().addListener((observable) -> {
final YourItem yourItem = row.getItem();
if (yourItem.isHover() ) {
// do something
} else {
// do something
}
});
return row;
});
(this code is from the answer here)
I missread, its about a TreeView. You can try an onMouseEntered or similiar within a cellfactory:
treeView.setCellFactory(tv -> {
final Tooltip tooltip = new Tooltip();
TreeCell<Path> cell = new TreeCell<Path>() {
#Override
public void updateItem(Path item, boolean empty) {
super.updateItem(item, empty);
}
};
cell.setOnMouseClicked(e -> {
// do something
});
cell.setOnMouseEntered(e -> {
// do something
});
return cell ;
});
I am trying to load a new anchorPane in the existing scene by removing the old anchorPane.Now i need to show the user that loading cursor and the action performed by the user should not happen(like button click or key press).
I have used but Cursor.WAIT but still the action can be performed.
anchorPane.getScene().SetCursor(Cursor.WAIT);
HomeController controller=new HomeController(stage,anchorPane);
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("/fxml/home.fxml"));
loader.setController(controller);
Parent root = null;
try {
root=(Parent) loader.load();
} catch (IOException e) {
LOGGER.error("Message is " + e);
e.printStackTrace();
}
anchorPane.getChildren().remove(0);
anchorPane.getChildren().add(root);
I have added Cursor.WAIT before this code.but i doesn't work.
Cursor.WAIT change only the icon of your cursor but it doesn't prevent you to interact with your view. If you want to prevent an user to interact with your view your could disable the elements like btn.setEnabled(false).
To show the user that you are peforming some background actions and he/she should wait until it's complete use tasks and dialogs.
Task task = new Task(new Runnable() { ... do stuff ... });
Dialog dialog = new Alert(AlertType.INFORMATION);
dialog.setTitle("Wait");
dialog.disableButton(ButtonType.OK);
task.stateProperty().addListener(
(observableValue, oldState, newState) -> {
if (newState == Worker.State.SUCCEEDED
|| newState == Worker.State.FAILED
|| newState == Worker.State.CANCELLED) {
dialog.close();
}
});
new Thread(task).start();
dialog.showAndWait();