Let's say I have a listbox and two buttons in a windows form application. When I click button1, "button1" is added to the listbox. When I click button2 "button2" is added as a new entry.
What I'm trying to do is have button2 added next to the previous entry instead of as a new entry. Something like "button1 + button2". Can this be done?
You just need to update an existing item on the form, not add a new one. Check this out:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
listBox1.Items.Add("A");
listBox1.Items[0] = listBox1.Items[0] + "B";
}
}
Related
So I have controller class with this object:
#FXML
private TextArea textArea;
then Im trying to add new MenuItem to its standard Items(that is "copy" and "select all")
#Override
public void initialize(URL location, ResourceBundle resources) {
ContextMenu contextMenu = textArea.getContextMenu();
X contextMenu.getItems().add(new MenuItem("chuj"));
textArea.setContextMenu(contextMenu);
and line marked with X gets me null pointer exception. Why?
Interesting part is that I can get contextMenu from textArea and set it back to its place with no error. I just cant add something new.
Unfortunately, there's no current way to access the default context menu, which is private API in the TextInputControl. This is a known bug.
If you set a context menu, it will remove the default one. You can recreate most of the functionality in the default context menu as these simply map to public methods defined in TextArea. The exceptions are "undo" and "redo".
So you can do something like this:
private List<MenuItem> createDefaultMenuItems(TextInputControl t) {
MenuItem cut = new MenuItem("Cut");
cut.setOnAction(e -> t.cut());
MenuItem copy = new MenuItem("Copy");
copy.setOnAction(e -> t.copy());
MenuItem paste = new MenuItem("Paste");
paste.setOnAction(e -> t.paste());
MenuItem delete = new MenuItem("Delete");
delete.setOnAction(e -> t.deleteText(t.getSelection()));
MenuItem selectAll = new MenuItem("Select All");
selectAll.setOnAction(e -> t.selectAll());
BooleanBinding emptySelection = Bindings.createBooleanBinding(() ->
t.getSelection().getLength() == 0,
t.selectionProperty());
cut.disableProperty().bind(emptySelection);
copy.disableProperty().bind(emptySelection);
delete.disableProperty().bind(emptySelection);
return Arrays.asList(cut, copy, paste, delete, new SeparatorMenuItem(), selectAll);
}
Now you can do
public void initialize() {
ContextMenu contextMenu = new ContextMenu();
contextMenu.getItems().addAll(createDefaultMenuItems(textArea));
contextMenu.getItems().add(new MenuItem("chuj"));
textArea.setContextMenu(contextMenu);
}
It's a bit of a hack (replicating functionality, etc) and you lose the undo/redo (which is a real issue); but it's the best I can suggest until they fix the bug. I suggest you vote for it...
I'm writing a view which navigates to a table entry's page displayed on the left side when a table entry (on the right) is chosen. This is similar to the addressbook tutorial on Vaadin's site, only I make use of the Navigator and views.
While I got the navigation to work (clicking on entry with id #12 navigates to localhost:8080/test/12) and a test label in the view's enter() gets changed to match the id, testTable.getItem(event.getParameters()) returns null for some reason so I can't access the entry.
The ValueChangeListener and enter() for the view are shown below.
class ValueChangeListener implements Property.ValueChangeListener {
Object testId;
#Override
public void valueChange(ValueChangeEvent event) {
// Navigate to a chosen table entry
this.testId = event.getProperty().getValue();
navigator.navigateTo("test/" + testId);
}
}
...
public void enter(ViewChangeEvent event) {
Object tmp = event.getParameters();
testName.setValue((String) tmp); // is set to the id
System.out.println(testTable.getItem(tmp) == null); // DEBUG: always returns true
}
I think you should change this:
System.out.println(testTable.getItem(tmp) == null);
to this:
String str = (String) tmp;
if (str != null && !str.isEmpty()) {
System.out.println(testTable.getItem(Integer.parseInt(str)) == null);
}
I think there's something wrong in how you manage you Navigator.
Firstly when you change view with Navigator you who should add a proper "URL fragment" with "#".
For example the Vaadin sampler uses:
http://demo.vaadin.com/sampler/#foundation
If in your URL there's no "#" ViewChangeEvent.getParameters() gives you null or isEmpty().
From the detailpage's view I try to push a new page on and I get this error: **
System.InvalidOperationException: Page must not already have a parent.
I keep trying different things but nothing works. Is there a way to push a page onto it, I mean, the detailpage is a navigationpage but it is a detailpage. Any and all help is much appreciated.
I am using xamarin forms labs ViewFactory.
//app.cs GetMainPage
var rootPage = ViewFactory.CreatePage<HomeVM>();
//in HomeView.xaml.cs, setting the detailpage to the list of messages
Detail = new NavigationPage(ViewFactory.CreatePage<MessagesVM>());
//This is in the MessagesView to show an individual message with a back button to the list of messages
Navigation.PushAsync(ViewFactory.CreatePage<MessageDetailVM>());
If you already have a NavigationPage, do not create another one to wrap your Detail instance in.
Detail = iewFactory.CreatePage<MessagesVM>();
Navigation.PushAsync(ViewFactory.CreatePage<MessageDetailVM>());
On my part, I also having the same error using MessagingCenter, but also solve it by unsubscribing/disposing after page closing/OnDisappearing.
Hope it helps.
public partial class MainPage : MasterDetailPage
{
public MainPage()
{
InitializeComponent();
MasterBehavior = MasterBehavior.Popover;
MessagingCenter.Subscribe<NavigationPage>(this, "Navigate", (pageItem) =>
{
Detail = pageItem;
IsPresented = false;
});
MessagingCenter.Subscribe<string>(this, "Logout", (s) =>
{
Application.Current.MainPage = new LoginPage("", "");
});
}
protected override void OnDisappearing()
{
MessagingCenter.Unsubscribe<NavigationPage>(this, "Navigate");
MessagingCenter.Unsubscribe<string>(this, "Logout");
base.OnDisappearing();
}
}
Unfortunately, I encountered this error again, and I solve it by using this setting the NavigationPage Parent property to null.
MessagingCenter.Subscribe<NavigationPage>(this, "Navigate", (pageItem) =>
{
pageItem.Parent = null; //solution
Detail = pageItem;
IsPresented = false;
});
Both answers before mine are pointing to the right direction, so this is just an addition. The key is in fact to not create the NavigationPage/NavigationView again.
In my project, I am using static objects for the MasterDetailPage, the NavigationView and the corresponding ViewModels in Xamarin Forms App class;
I am only creating an instance if their Value is null, which is likely to happen only if the app was closed before (no matter if closed by the user or the OS). If the app is still running (resumed), I am just using the already existing objects to restore the state.
This solved all these problems for me, and I hope it is helpful for someone else.
Try using the Navigation property of the Detail object like this:
Detail.Navigation.PushAsync(page);
To push a new page on my Detail I use the code below:
Note there I'm using a ListView with page options in MasterDetailPage
private void ListView_ItemSelected(object sender, SelectedItemChangedEventArgs e)
{
var item = e.SelectedItem as MainMenuItem;
if (item == null)
return;
var page = (Page)Activator.CreateInstance(item.TargetType);
//Detail = new NavigationPage(page);
Detail.Navigation.PushAsync(page);
IsPresented = false;
MasterPage.ListView.SelectedItem = null;
}
Update:
I want to get a node's property value that has been changed after clicking save button and before saving the changes programmatically, on content tab in BackOffice.
The node could contain many properties. When the save button is clicked, I want to first get the new changed value for the node's properties. I think Umbraco should have APIs to get those in server side.
Any idea would be very much appreciated.
You want to wire into the Document.BeforeSave method in an IApplicationEventHandler class. Like so (assuming you're changing bodyText from "apple" to "orange"):
using umbraco.cms.businesslogic.web;
using Umbraco.Core;
using Umbraco.Web;
namespace ClassLibrary1
{
public class Class1 : IApplicationEventHandler
{
public void OnApplicationStarted(UmbracoApplication httpApplication, ApplicationContext applicationContext)
{
Document.BeforeSave += new Document.SaveEventHandler(Document_BeforeSave);
Document.AfterSave += new Document.SaveEventHandler(Document_AfterSave);
}
void Document_BeforeSave(Document sender, umbraco.cms.businesslogic.SaveEventArgs e)
{
// your code goes here!
sender.getProperty("bodyText").Value // returns apple
}
void Document_AfterSave(Document sender, umbraco.cms.businesslogic.SaveEventArgs e)
{
// your code goes here!
sender.getProperty("bodyText").Value // returns orange
}
public void OnApplicationStarting(UmbracoApplication httpApplication, ApplicationContext applicationContext)
{
// unused
}
public void OnApplicationInitialized(UmbracoApplication httpApplication, ApplicationContext applicationContext)
{
// unused
}
}
}
I tested this in Umbraco 4.11
Cheers
Jonathan
What you could do is use a jquery event handler, that is targeted at the field in the umbraco admin you want to check for changes. This example will work by finding the label of the umbraco field you want to monitor and then adding a jquery event handler that will fire when the field that is the sibling to the label is changed - this example will work for any changes to the 'Name' field that is on every node's 'properties' tab. Different field types will hold the value differently, so $(this).val() should usually work for most - but not all field types.
Drop this into the end of \umbraco\editcontent.aspx
<script type="text/javascript">
$(document).ready(function () {
$("div.propertyItemheader:contains('Name') + div.propertyItemContent").keyup(function () {
alert("field changed");
});
});
</script>
I have a combobox, that I populate from a web service:
public Configure()
{
InitializeComponent();
WebServiceSoapClient ws = new WebServiceSoapClient();
ws.GetTypesCompleted += new EventHandler<GetTypesCompletedEventArgs>(OnGetTypeCompleted);
ws.GetTypesAsync();
}
void OnGetTypeCompleted(object sender, GetTypesCompletedEventArgs e)
{
if (e.Result != null)
{
List<CodeTableItem> source = e.Result.ToList<CodeTableItem>();
lstType.ItemsSource = source;
lstType.SelectedIndex = -1;
}
}
So when I set the ItemSource property, SelectionChanged event gets fired with SelectedIndex = 0, but user hasn't made this selection yet and I need this list to have no selected value, so I'm setting SelectedIndex to -1, as you can see. As a result, SelectionChanged is called twice.
Can I make it be called only when user selects the item?
Thanks!
I'm using Silverlight 3 and VS 2008
Instead, modify your code so that the SelectionChange event handler isn't defined until after the itemssource and selected index are set.
void OnGetTypeCompleted(object sender, GetTypesCompletedEventArgs e)
{
if (e.Result != null)
{
List<CodeTableItem> source = e.Result.ToList<CodeTableItem>();
lstType.ItemsSource = source;
lstType.SelectedIndex = -1;
lstType.SelectionChanged += new SelectionChangedEventHandler(lstType_SelectionChanged);
}
}
In our application we implemented some code that would set a boolean flag based on the Control.LeftMouseButtonUp() event. When this has been set, it would mean that the user has interacted with the field, and so we can handle the SelectionChanged with different behaviour.
Over the development lifetime of our application this approach was essential so that default bindings would trigger our SelectionChanged logic when we didn't want it to.
If you are an MVVM purist, you'll need to expose the VM as a member variable and then set the bool flag in the VM.
HTH,
Mark