I've written a simple custom control which extends HBox and contains a TextField and Button. As for many controls, it makes sense to have a label alongside describing its purpose, and I want users on mnemonic-capable platforms to access the control easily, more specifically giving focus to the button instance.
My first thought was to assign a focus listener to the custom control, on an assumption that the target node would be focused on label activation, but this doesn't work. On delving into JavaFX source, I find the Label.labelForProperty() uses a NodeHelper$NodeAccessor.setLabeledBy(Node, Node) method, but can't get beyond that as I can't find a solid implementation of the NodeHelper$NodeAccessor interface. My guess is that this utility class only maps associations with targets it deems suitable, and for some reason my custom control isn't.
My second thought is to open up access to the button, which can then be directly assigned as the target, but for obvious reasons this is a poor choice, and I'd far prefer to leave the button inaccessible.
Has anyone encountered this scenario and found a viable solution/workaround without compromising the visibility of internal implementation details of a custom control?
This is a simple workaround that doesn't need your Button to have public visibility:
public class YourCustomClass {
private TextField tf;
private Button btn;
public void registerLabel(Label label) {
label.setLabelFor(btn);
}
}
Related
How can I make it after ticking the box and it turns uneditable right away?
This question is somewhat loaded because the answer is, it depends.
Your screenshot makes it look like that control is in a grid row, which would imply the control is connected to a datasource. If that's the case, do you want only the checkbox to be disabled or the entire row?
You would probably put code in the datasource field's modified method or the datasource's active method.
If the checkbox is a standalone control, you would override the clicked method with something like:
public void clicked()
{
super();
if (this.checked())
this.enabled(false);
}
I believe it's due to Field properties in table.
Seems like it restricts edit after creation.
Otherwise - check code on form (or class maintaining the form). It might be on Control/Field/Datasource/Table modify method.
In Xamarin Forms, I have a custom view with a BindableProperty:
public static readonly BindableProperty SelectedItemProperty
= BindableProperty.Create(nameof(SelectedItem), typeof(object), typeof(OneOfNButtons), null,
BindingMode.TwoWay);
I use that custom view within a custom page:
<exodus:OneOfNButtons ItemsSource="{Binding Tabs}" SelectedItem="{Binding SelectedTab, Mode=TwoWay}"/>
The two-way binding works as expected.
Now I want to trigger an animation that moves the entire OneOfNButtons control up to middle of page, so I can show related content below it, whenever SelectedItem changes. That is, it is not the primary focus of the page, it is down at bottom. If user is interested in it, they click any of the buttons on it, and half the page becomes dedicated to that topic, with the row of buttons acting like tabs, just above the content.
I understand DataTriggers, but those are for specific values. I'm looking for a trigger on any change to SelectedItem property. (If the logic belonged within the custom control itself, I could add code to the SelectedItem setter.)
This is logic specific to the page, so it belongs with the page; is not part of the custom control.
This is logic specific to this UI, so it belongs with the page, not with page's view model.
I've written the question as "invoke a code behind method", because that is the technique I would like to know how to do in general, even if this specific situation could be handled entirely in XAML.
Though I would also be glad to know how to trigger other XAML, on any change.
(If you know a WPF XAML technique, it might work in Xamarin Forms, though XAML here is more limited. Specifically, X-Forms bound properties are not "DependencyProperty"s, so I don't know how to "chain" properties.)
There are a number of XAML & data binding questions on SO, but all the ones I have found either discuss binding between view and model, or within a single view (I need a change in one view to affect the containing view), or involve messaging between the views (the sub-view does not and should not know about this requirement, so messaging isn't applicable), or triggering on specific values, or are for WPF and don't appear to be supported in Xamarin Forms.
You can handle any property changed events with this.
this.YourControl.PropertyChanged += YourControlPropertyChanged;
private void YourControlPropertyChanged(object sender,PropertyChangedEventArgs e)
{
if(e.PropertyName == "SelectedItem")
{
//Code
}
}
I need to connect some simple filter functionality, to a mouse click on a QTreeView header item. Simple enough, I implemented a slot function that connects to:
QTreeView::header()->sectionClicked(int)
After setting
QTreeView::header()->setSectionsClickable(true)
,sectionClicked is emitted any time I click on a header that is highlighted by the default hover effect that any clickable header will produce.
The issue is, hovering over some areas in clickable headers will not be recognized. Hence, in these parts there is no highlight and I will not get any sectionClicked triggers. I traced it back further and derived my own class from QHeaderView and put some output into mouseMoveEvent.
class MyHeaderView : public QHeaderView
{
Q_OBJECT
public:
MyHeaderView(QWidget* parent = 0)
: QHeaderView(Qt::Horizontal, parent)
{
setMouseTracking(true);
}
protected:
virtual void mouseMoveEvent(QMouseEvent* event)
{
qDebug() << event->pos();
}
};
While leaving all QTreeView settings as they were, I set an instance of this class to be the header via
QTreeView::setHeader(QHeaderView*)
I could see, that in all areas were the hover effect failed, I did not get the debug output you can see in the overridden mouseMoveEvent.
As a result I am assuming, that the mouse tracking is not working correctly.
The overall application I am working on is quiet big, so I set up a stand alone example, for all of this. To my surprise, everything works as expected. I am clueless, how I should proceed with this. Can anyone think of reasons for the mouse tracking to fail in some parts of a widget? Could it be a frame rate issue tied to lack of performance? Are there settings on widgets that affect the overall mouse tracked area? Can parent widgets affect mouse tracking?
In my application I have a controller class that handles a lot of application logic connected to various signals the tree view emits. This class is not suppost to render any visualization. Hence, it would be the most reasonable choice to derive from QObject. After a while I noticed, that it was in fact derived from QWidget. Being a QWidget I am guessing it tries to render some sort of visual representation, which the overlays the tree view. That's why I don't get any mouse events in some parts of the header.
After changing the base class of my controller to QObject, everything works fine again.
In my project I am using a custom circle-shaped button widget derived from the QWidget class. I have added several of these widgets to a parent widget.
When one of these custom buttons is clicked, how do I find out which one was clicked?
Adding custom button to parent widget:
void ShotViewCTRL::addShot(QString shotNanme)
{
ShotButton *btnShot=new ShotButton(this);
btnShot->shotName=shotNanme;
connect(btnShot,SIGNAL(Shot_Selected()),this,SLOT(SHOT_CLICKED()));
btnShot->CreateButton();
btnShot->show();
}
My parent widget is ShotViewCTRL (inherits from QWidget), the child widget is ShotButton (custom control, inherits from QWidget).
The control is working fine. It's sending sending to parent object. In my problem, I added the same custom control 10 times.
I need to find which control was clicked? Please help me find the solution.
I have referred to the Qt documentation to find the child widget, but I did't understand. Some sample code would be great.
QSignalMapper is what you are looking for. With QSignalMapper, you can add something like an Id (or even a pointer to the QButton itself) as additional data to the signal emittance and you have to adjust your slot so it takes additional data (ID or Pointer).
Then either distinguish in the slot itself by the id you give your objects some virtual function type() so you can distinguish with that or even try casting and catch errors (Tip: don't try the last method, it may work differently on different compiler).
You can use the QObject::Sender function to find which QObject sends the signal. Regarding the first warning in the doc, it's what you are searching for.
you specify different slots for different buttons with same signal.with that you can recognize the different button click
Just that, if you embed an icon:
[Embed(source='icons/checkmark.png')]
private static var CheckMark:Class;
You end up with a dynamic class. You can pretty easily assign the icon to a button at runtime by calling the setStyle method:
var btn:Button = new Button();
btn.setStyle("icon", CheckMark);
But what if you wanted to alter the icon at runtime, like changing it's alpha value or even redrawing pixels, before assigning it to the button?
So far I can't find a satisfactory answer...
This is the only answer I could find that seemed close: Dynamic Icons (example with View Source)
His solution involves a custom "DynamicIcon" class which is used in the button's icon setting, and a custom Button class which adds one method to the Button class to draw dynamic icons.
The end result is that you are able to send BitmapData to the DynamicIcon class, which will show up in the button. So, embed your image, instantiate your asset class, get the bitmapasset and modify it however you need to and send the bitmapData to the icon.
It's an interesting problem and it seems like there should be an easier solution, but this works without a lot of hassle.
The way I'd solve this is to implement a programmatic skin class that draws the icon itself manually. There's probably more work you'll have to do to ensure the button calculates the correct size as if it has an icon even though it doesn't. You may have to poke through the Button source code to look at how the reference to the icon is stored.
I love just creating programmatic skins that do exactly what I want and then using interesting CSS declarations to modify states - for instance:
button.setStyle("customIconAlpha", .4);
and then of course the skin or the custom button class would have:
var alpha:Number = getStyle("customIconAlpha") as Number;
(not sure if you have to typecast that one)
The big problem I found with programmatic skins is that the button refuses to measure the width/height. I easily got around this by overriding the get methods for each:
override public function get width():Number { return WIDTH; }
override public function get height():Number { return HEIGHT; }
In my case I needed to modify buttons in a TabNavigator, hence no easy way to subclass the button. Thankfully, the parent of each skin is the button, so using static methods within your skin, you can identify the instance of the Button to which the icon skins belong.
If you're using the cover-all "icon" style, a new skin object will be created for each state. So you'll need to keep this in mind when changing the state of the icons.