It looks like the AutoCompleteTextField is firing a suggestion selection event on load. I test this with a ListModel. You can recreate this issue with the code below from a barebone hello world project.
public void start() {
if (current != null) {
current.show();
return;
}
Form hi = new Form("Hi World");
ListModel<String> suggestionsModel = new DefaultListModel<String>();
suggestionsModel.addItem("Apple");
suggestionsModel.addItem("Banana");
suggestionsModel.addItem("Chocolate");
suggestionsModel.addItem("Elk");
suggestionsModel.addItem("Fish");
AutoCompleteTextField search = new AutoCompleteTextField(suggestionsModel);
suggestionsModel.addSelectionListener(new SelectionListener() {
#Override
public void selectionChanged(int oldSelected, int newSelected) {
System.out.println("SUGGESTION SELECTED"+suggestionsModel.getSelectedIndex());
}
});
hi.add(search);
hi.show();
}
If you run the code, you can see that the "SUGGESTION SELECTED0" gets printed twice confirming that the selection is firing on load and selecting the first suggestion by default.
This is causing me issues. I am searching for an object and then if found, I am displaying its attributes to the user. Per this issue, the attributes for the first object is getting displayed by default on load.
This is the behavior of the data change listener which is "over eager", we won't change it as there are some edge cases that depend on this behavior (e.g. paste, instant edit type etc.).
Working with this is pretty easy:
if(currentValue != lasValue) {
....
}
Related
i am new to wpf and i need to open up a pop up a new window on grid row click which contains lots of data and controls on it.i am confused with the correct approach. i am using mvvm pattern.should i make a window control or user control or something else. and how to open that pop up inside a function. please help with example
If I need to display a new Window in my MVVM-Application I use the following approach:
At first I have an interface with a method to show the new dialog:
internal interface IDialogManager
{
void DisplayData(object data);
}
And an implementation like:
internal class DialogManager : IDialogManager
{
public void DisplayData(object data)
{
LotOfDataViewModel lotOfDataViewModel = new LotOfDataViewModel(data);
LotOfDataView lotOfDataView = new LotOfDataView
{
DataContext = lotOfDataViewModel
};
lotOfDataView.ShowDialog();
}
}
LotOfDataViewModel and LotOfDataView are the new Dialog where you want to show your data.
In your actual ViewModel you introduce a new property like:
private IDialogManager dialogManager;
private IDialogManager DialogManager
{
get { return dialogManager ?? (dialogManager = new DialogManager()); }
}
And the you can show your large data with:
DialogManager.DisplayData(myData);
I'm trying to access a native Wpf control property within the UI test framework (MS UI Tests). My specific issue is that, when I try accessing a WpfButton control property (e.g., IsVisible) using the function call WpfButtonObject.GetProperty("IsVisible"), the exception "System.NotSupportedExceptions" occurs. I'm able to see this WpfButton property using Snoop; so, I'm wondering if the GetProperty call is correct? Please see my related code below. Thanks for any insight.
UIMap.cs: Test function for a pressing a WpfButton. Please note the call uIButton.GetPropery("IsVisible"). This is where the exception occurs:
public void PressButtonTest()
{
WpfButton uIButton = this.UIMainWindowWindow.UIButtonButton;
object state = uIButton.GetProperty("IsVisible"); // Throws SystemNotSupportedException exception
bool stateBool = (bool)state;
Assert.IsTrue(stateBool, "Button is visible");
PressButton();
}
UIMap.Designer.cs: WpfButton property:
public WpfButton UIButtonButton
{
get
{
if ((this.mUIButtonButton == null))
{
this.mUIButtonButton = new WpfButton(this);
#region Search Criteria
this.mUIButtonButton.SearchProperties[WpfButton.PropertyNames.AutomationId] = "button";
this.mUIButtonButton.WindowTitles.Add("MainWindow");
#endregion
}
return this.mUIButtonButton;
}
}
Here's what I've done:
Point point;
bool isClickable = uIButton.TryGetClickablePoint(out point);
Assert.IsTrue(isClickable, "No clickable point was found, button not visible.");
By the way, your message in your Assert (2nd parameter) is inaccurate because it's only used on fail... in your case, when the button would not be visible. So in your output it would say "Button is visible" on failure when in fact it was not.
In page edit mode I want to show a read-only text that is based on a page property value. The text could for example be "A content review reminder email will be sent 2015-10-10", where the date is based on the page published date + six months (a value that will be configurable and therefore can change anytime). So far I've tried to accomplish something like this by adding another property on the page.
I've added the property CurrentReviewReminderDate to an InformationPage class we use. In page edit mode the property name is shown, but it doesn't have a value. How do I do to show the value in page edit mode (preferably as a label)?
[CultureSpecific]
[Display(
Name = "Review reminder date",
Description = "On this date a reminder will be sent to the selected mail to remember to verify page content",
Order = 110)]
[Editable(false)]
public virtual string CurrentReviewReminderDate
{
get
{
var daysUntilFirstLevelReminder =
int.Parse(WebConfigurationManager.AppSettings["PageReviewReminder_DaysUntilFirstLevelReminder"]);
if (CheckPublishedStatus(PagePublishedStatus.Published))
{
return StartPublish.AddDays(daysUntilFirstLevelReminder).ToString();
}
return "";
}
set
{
this.SetPropertyValue(p => p.CurrentReviewReminderDate, value);
}
}
EPiServer internally uses the GetPropertyValue method (i.e. the opposite of SetPropertyValue) when retrieving content for the UI.
This makes sense, otherwise your "made-up" value would be stored as the real value whenever the content is saved. This would make fall-back values etc impossible to implement.
So, this is by-design (and quite wisely so) in EPiServer. :)
However, you can customize how properties work by:
Using custom editors by applying UI hints
Modifying property metadata (for example, to display a generated value as a watermark in a textbox without interfering with the actual value being saved)
I could be misunderstanding what you're trying to do, but off the top of my head it looks like a custom editor could be a viable option for your use case?
Another solution would be to hook into the LoadedPage-event and add the value from there. This might not be the best way performance-wise since you need to do a CreateWritableClone, but depending on the site it might not matter.
[InitializableModule]
[ModuleDependency(typeof(EPiServer.Web.InitializationModule))]
public class EventInitialization : IInitializableModule
{
public void Initialize(InitializationEngine context)
{
ServiceLocator.Current.GetInstance<IContentEvents>().LoadedContent += eventRegistry_LoadedContent;
}
void eventRegistry_LoadedContent(object sender, ContentEventArgs e)
{
var p = e.Content as EventPage;
if (p != null)
{
p = p.CreateWritableClone() as EventPage;
p.EventDate = p.StartPublish.AddDays(10);
e.Content = p;
}
}
}
I asked this question in a similar post but there have been significant updates since then, but still no results so I will try to re-ask the question with the updated information.
Basically I have a pivot view with 4 pivot items. If I create the scenario where I hit the windows key then rapidly press the back key my application will reopen without reconstructing (this is the expected outcome). The functionality of the application is there. I can press application bar buttons etc.
What doesn't work is the pivot items are frozen. If I was on Pivot item A and I press the start and back button quickly I come back to Pivot Item A. If I try to switch Pivot Items, the screen does not update, its "frozen" on Pivot Item A BUT the functionality of Pivot Item B is there. (I know this because the application bar Icons for Pivot Item B are now showing).
I have read many articles on proper tombstoning scenarios and how to approach this problem. My data IS being tombstoned correctly, and upon reactivation the tombstoned data works. No objects are null so I don't have any exceptions being thrown at me.
I check to see if I need to reload the Main ViewModel (I don't need to in this case so the UI elements being created initially are not being re created).
What does fix the problem however is if the application is reconstructed. Lets say I go to the marketplace from my app, let it finish loading and press back, My application will be refreshed and working fine since it properly deactivated and reconstructed istelf. I don't rely on constructors doing all the work so I am not missing any key elements not being set when they aren't fired in the windows/back button scenario.
Does anyone have any idea why my screen would not be updating?
constructor/loaded event/on navigated to event
public MainPage()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(MainPage_Loaded);
}
private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
if (App.firstTimeLoading == true)
{
App.firstTimeLoading = false;
}
BuildApplicationBar();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
this.DataContext = App.ViewModel;
App.viewIdentifier = StringResource.MainPageView;
if (!App.ViewModel.IsDataLoaded)
{
App.ViewModel.LoadData();
String bookTitle;
App.Parser.appBookInfoDict.TryGetValue(CPlayerInventoryKeys.kInventoryKeyTitleShortTitle, out bookTitle);
PivotBackground.Title = bookTitle.ToUpper();
CreatePivotItems();
}
if (App.playerController.chapterPlayer.Source == null)
App.restoreStateClass.RestoreState();
//applies the proper background image
if (App.isDarkTheme)
{
BitmapImage bitmapImage = new BitmapImage(new Uri(StringResource.PanoramaBlackImage, UriKind.Relative));
BackgroundImage.ImageSource = bitmapImage;
BackgroundImage.Opacity = .85;
}
else
{
BitmapImage bitmapImage = new BitmapImage(new Uri(StringResource.PanoramaWhiteImage, UriKind.Relative));
BackgroundImage.ImageSource = bitmapImage;
BackgroundImage.Opacity = .5;
}
if (App.firstTimeLoading == false && PivotBackground.SelectedItem != SuggestedPivotItem)
BuildApplicationBar();
else if (PivotBackground.SelectedItem == SuggestedPivotItem)
{
BuildMarketPlaceApplicationBar();
}
base.OnNavigatedTo(e);
}
I found the answer. Since I had a media element open (play/paused) and I was implementing the "non tombstoned" method of hitting windows key and back button very quickly, the media element source was corrupt. Even though I reset this source, apparently it can be ignored and not function properly. All I had to do was add a line of code to the Application Deactivated handler.
private void Application_Deactivated(object sender, DeactivatedEventArgs e)
{
App.MainAudioPlayer.Source = null; //(only showing line added)
}
The behavior you are describing seems to be solely related to the way you are manipulating data internally and constructing your layout. I tested this both in the emulator and on a couple of physical devices, both producing normal output (even when bound to a view model).
Try creating a new Pivot-based application (without all your data - just using the default template) and see if the problem persists. Also worth mentioning - are you testing on a device or in the emulator?
Are you using transitions from the toolkit?
Are they defined in XAML?
If so that could be the issue. There's a bug which is fixed in the next version.
The solution for now is to remove the transitions or define them in code.
I have a prism/wpf/mef solution that contains an AvalonDock. I created a RegionAdapterBase<Pane> class that handles creating and removing the Panes from AvalonDock.
Heres the problem I'm running into:
I click a button in my menu and a view is registered with a region and displayed in my DocumentPane
I click the close button in AvalonDock to close the tab and remove the view
I click the same menu button to add it back again
I receive the error:
"Specified element is already the
logical child of another element.
Disconnect it first."
So... this tells me that something is lingering that I need to remove, but I cannot figure out where it is. Heres some code from my RegionAdapter:
private void OnViewsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e, IRegion region, Pane regionTarget)
{
if (e.Action == NotifyCollectionChangedAction.Add)
{
foreach (object item in e.NewItems)
{
UIElement view = item as UIElement;
if (view is ITabViewInfo)
{
if (view != null)
{
DockableContent newContentPane = new DockableContent()
{
Content = item,
Title = ((ITabViewInfo)view).TabViewTitle,
Icon = new Image()
{
Source = new BitmapImage(((ITabViewInfo)view).TabViewIcon)
}.Source,
IsCloseable = ((ITabViewInfo)view).IsCloseable,
HideOnClose = ((ITabViewInfo)view).IsHideOnClose
};
newContentPane.Closed += (contentPaneSender, args) =>
{
Debug.WriteLine("Removing view from region", "Prism");
region.Remove(item);
};
regionTarget.Items.Add(newContentPane);
newContentPane.Activate();
}
}
}
} else if (e.Action == NotifyCollectionChangedAction.Remove) {
regionTarget.Items.Clear();
}
}
From my debug lines, the DocumentPane and region views are properly being destroyed... when I click to add the item back to the view, I get the above error message on the line that does:
Content = item,
Heres the code from my module that runs when the menu button is pressed:
if (_regionManager.Regions["MainRegion"].Views.Any(m => m.GetType() == typeof(Views.ClassicFrontierView)))
{
Debug.WriteLine(_regionManager.Regions["MainRegion"].Views.Count());
}
else
{
Debug.WriteLine("Adding view to region", "Prism");
_regionManager.RegisterViewWithRegion("MainRegion", typeof(Views.ClassicFrontierView));
}
Any idea what I'm missing?
Do you create a new View each time or you trying to show existing View several times? If second is correct I would try this:
else if (e.Action == NotifyCollectionChangedAction.Remove) {
foreach (DockableContent content in regionTarget.Items)
content.Content = null;
regionTarget.Items.Clear();
}
Instead of handling the Closed event (which may have lost a reference to the underlying view), I handle the Closing event.
This worked, however, when I tried to re-open the tab, it was displaying the same instance. After reading this In Composite WPF (Prism), what is the difference between IRegion.Add and IRegionManager.RegisterViewWithRegion? I changed this:
_regionManager.RegisterViewWithRegion("MainRegion", typeof(Views.ClassicFrontierView));
to this:
_regionManager.Regions["MainRegion"].Add(new Classic.Views.ClassicFrontierView());
I still have to do some research with Prism / avalondock to make sure there will be no memory leaks, but as of now it appears to be working.
You likely need to remove it from regionTarget as well.
You can use Snoop to see what hasn't been removed from the Visual Tree and then attempt to find which container you need to remove your element from. Other possibilities are things like an unfrozen Icon image, etc.