ItemInvoked vs SelectionChanged - events

In Windows UWP, what is the difference between the ItemInvoked and SelectionChanged events for a NavigationView? The API reference states
ItemInvoked
Occurs when an item in the menu receives an interaction such as a click or tap.
SelectionChanged
Occurs when the currently selected item changes.
It seems to me that SelectionChanged can detect when navigation occurs even by some method other than clicking a NavigationView.MenuItem, so would be the better, more encompassing option to use?
Or are there different use cases for each?

The main difference would be that the SelectionChanged event is executed only once, but if you click the selected item repeatedly, it is not fired. ItemInvoked on the other hand will execute each time an item is clicked even if it is selected already.
Also - SelectionChanged event will execute when you manually set SelectedItem in code.

Another thing that might be useful to note is that ItemInvoked fires before SelectionChanged when you click on a NavigationView item

I was recently struggling with this question and having a problem when using the SelectionChanged Event. Successive clicks on the same Menu Item yielded no result.
Then I found this blog post (https://blogs.msdn.microsoft.com/appconsult/2018/05/06/using-the-navigationview-in-your-uwp-applications/) which suggested using the ItemInvoked Event for the same reason given in answer #1.
This did not work for me as posted in the Blog but after changing the code to use the InvokedItemContainer Tag property the solution worked just fine.
I have included the test code I used to verify the solution.
private void NvTopLevelNav_ItemInvoked(NavigationView sender, NavigationViewItemInvokedEventArgs args)
{
if (args.IsSettingsInvoked)
{
contentFrame.Navigate(typeof(SettingsPage));
}
else
{
string navTo = args.InvokedItemContainer.Tag.ToString();
if ( navTo != null)
{
switch (navTo)
{
case "Nav_Home":
contentFrame.Navigate(typeof(HomePage));
break;
case "Nav_Shop":
contentFrame.Navigate(typeof(ShopPage));
break;
case "Nav_ShopCart":
contentFrame.Navigate(typeof(CartPage));
break;
case "Nav_Message":
contentFrame.Navigate(typeof(MessagePage));
break;
case "Nav_Print":
contentFrame.Navigate(typeof(PrintPage));
break;
}
}
}
}
<Grid>
<NavigationView x:Name="nvTopLevelNav"
Loaded="NvTopLevelNav_Loaded"
Margin="0,12,0,0"
SelectionChanged="NvTopLevelNav_SelectionChanged"
ItemInvoked="NvTopLevelNav_ItemInvoked"
IsTabStop="False"
Header="Lets Go Shopping">
<NavigationView.MenuItems>
<NavigationViewItem Icon="Home" Content="Home" Tag="Nav_Home" />
<NavigationViewItem Icon="Shop" Content="Shop" Tag="Nav_Shop" />
<NavigationViewItem Content="Shopping Cart" Tag="Nav_Cart">
<NavigationViewItem.Icon>
<FontIcon Glyph="[Insert Hex Decimal Value Here. See Segoe MDL2 below for details.]"/>
</NavigationViewItem.Icon>
</NavigationViewItem>
<NavigationViewItem Icon="Message" Content="Message" Tag="Nav_Message" />
<NavigationViewItem Icon="Print" Content="Print" Tag="Nav_Print" />
</NavigationView.MenuItems>
<Frame x:Name="contentFrame"></Frame>
</NavigationView>
</Grid>

Related

.net maui CarouselView is not quite compatible with Slider control: CarouselView swipe operation takes over Slider's drag action

.net maui app.
Dragging value element along the slider bar does not work if the the slider put into CarouselView's template like this:
<CarouselView ItemsSource="{Binding Items}">
<CarouselView.ItemTemplate>
<DataTemplate>
<Slider Minimum="0" Maximum="30" WidthRequest="200" />
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
CarouselView takes over the swipe event for scrolling through the items, and Slider does not get the event (DragStarted is not even called). You can actually click along the slider bar to change its value, so it's not completely frozen, but not how it's supposed to work. Drag & drop is main way user deal with slider control.
Could anyone advise any workaround? I want users to be able scroll through carousel view items also. It's just if they swipe inside the control, event should not handed over to its parent container, if it's possible to do so.
If I add it outside of the corouselview, combine both in Grid and use padding to align slider inside the corouselview, it works as expected, but I need to add lots of additional code, calculate the desirable location and redirect all bindings, which ends up to be an awkward workaround.
At first, I don't suggest you use the slider in the CarouselView. Becasue you want the same behavior has two effects. There is a conflict between them.
But for the android, you can use the custom handler to deal with the swipe event.
Put the Handler class in the /Platform/Android:
public class MySliderHander : SliderHandler
{
protected override void ConnectHandler(SeekBar platformView)
{
base.ConnectHandler(platformView);
platformView.SetOnTouchListener(new SliderListener());
// the listener will make the slider deal with the swip event not the CarouselView.
}
}
Put the SliderListener class in the /Platform/Android
public class SliderListener : Java.Lang.Object, IOnTouchListener
{
public bool OnTouch(global::Android.Views.View v, MotionEvent e)
{
if (e.Action == MotionEventActions.Down || e.Action == MotionEventActions.Move)
{
v.Parent.RequestDisallowInterceptTouchEvent(true);
}
else
{
v.Parent.RequestDisallowInterceptTouchEvent(false);
}
return false;
}
}
And in the MauiProgram.cs:
builder
                  .UseMauiApp<App>()      
                  .ConfigureMauiHandlers(handlers => {
#if ANDROID
                        handlers.AddHandler(typeof(Slider), typeof(YourProjectName.Platforms.Android.MySliderHander));
                  #endif
                  })
In addition, the Slider's height is same as the CarouselView. So you can use a frame to contain the Slider and swipe the CarouselView by swiping the frame.

Using a Command Bar inside of the NavView Navigation Pane UWP

I'm struggling to create the UI I have in my head and to date have been fairly unsuccessful.
I'm trying to create a Main Page which hosts my NavView and inside of by NavView I wish to have a command bar which will control which NavViewItems are visible. I have created a quick image of what I'm trying to achieve.
In my example I have the home button in the command bar activated which displays
Nav Item Header
Navigation Item 1
etc...
I want to be able to click documents and have the indicator switch to documents and hide the navigation items corresponding to Home and show the navigation items corresponding to Documents.
Finally, I want the command bar to collapse when the NavView pane is compact but the user should be able to click the Command bar button and expand the command bar to change between Home, Documents etc.
Really looking for any help/advice for the best places to start.
I'm still learning the UWP controls and Xaml.
I think you should use a SplitView instead of NavigationView outside, and then,
inside the Pane of the Splitview, use a NavigationView with some trick to achieve what you desired.
Key points are:
Keep the NavigationView's PaneDisplayMode LeftComact
don't use the PaneToggleButton in the NavigationView to prevent
user from changing PaneDisplayMode by clicking it, use a custom one instead to open and close pane.
Change the PaneDisplayMode of the NavigationView to Top when
pane opens, and backt to LeftComact again when pane closes.
Here is what I have achieved with NavigationView inside Splitview.Pane:
You can decorate it and make it more visually satisfying, like adding an AutoSuggestBox or Setting button, but that's the basic. Btw, don't use the NavigationView's Setting button, as I have seen it behaving strangely here.
XAML:
<SplitView
x:Name="Split"
DisplayMode="CompactInline"
CompactPaneLength="40">
<SplitView.Pane>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition />
</Grid.RowDefinitions>
<Button
Click="Button_Click">
<SymbolIcon Symbol="List"/>
</Button>
<NavigationView
Grid.Row="1"
x:Name="NavView"
PaneDisplayMode="LeftCompact"
CompactPaneLength="{x:Bind Split.CompactPaneLength}"
IsBackButtonVisible="Collapsed"
IsPaneToggleButtonVisible="False"
IsSettingsVisible="False"
SelectionChanged="NavView_SelectionChanged">
<NavigationView.MenuItems>
<NavigationViewItem x:Name="HomeItem" Icon="Home" VerticalAlignment="Stretch"/>
<NavigationViewItem x:Name="DocumentItem" Icon="Document" />
<NavigationViewItem x:Name="PeopleItem" Icon="People" />
</NavigationView.MenuItems>
<ContentControl>
<ListView
x:Name="ItemList"/>
</ContentControl>
</NavigationView>
</Grid>
</SplitView.Pane>
</SplitView>
Code behind:
public sealed partial class MainPage : Page
{
public List<string> HomeItemList;
public List<string> DocumentItemList;
public List<string> PeopleItemList;
public MainPage()
{
InitializeComponent();
HomeItemList = new List<string> { "HomeItem1", "HomeItem2", "HomeItem3" };
DocumentItemList = new List<string> { "DocumentItem1", "DocumentItem2", "DocumentItem3" };
PeopleItemList = new List<string> { "PeopleItem1", "PeopleItem2", "PeopleItem3" };
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Split.IsPaneOpen = !Split.IsPaneOpen;
if (Split.IsPaneOpen)
{
NavView.PaneDisplayMode = NavigationViewPaneDisplayMode.Top;
}
else NavView.PaneDisplayMode = NavigationViewPaneDisplayMode.LeftCompact;
}
private void NavView_SelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
{
if (args.SelectedItem != null)
{
Split.IsPaneOpen = true;
NavView.PaneDisplayMode = NavigationViewPaneDisplayMode.Top;
if (sender.SelectedItem == HomeItem)
ItemList.ItemsSource = HomeItemList;
else if(sender.SelectedItem == DocumentItem)
ItemList.ItemsSource = DocumentItemList;
else if(sender.SelectedItem == PeopleItem)
ItemList.ItemsSource = PeopleItemList;
}
}
}
Hope that helps.
First thing is to decide if you want to use NavigationView. In XAML controls are defined by their behavior (properties and methods that they implement), while the visual appearance is irrelevant and can be altered completely. If NavigationView is right for your task then you can alter its style partially or completely - in XAML editor right click on it, then click Edit Template > Edit a Copy. Now you'll get the XAML style definition that defines appearance of NavigationView, that's the place to start.
But it might be very well that you can't use NavigationView and that starting with SplitView might be a better idea as #Muzib said.
Not sure if this is a good idea for learning XAML, but you'll learn one thing - XAML can be customized to the great extent, but doing it may also be a very complex task.
I think there are a few problems from the UX perspective.
Not all the navigation items are shown at once and a used must expand the menu to change between the sets of items.
The positions of the navigation items changes when the navigation pane is expanded. Currently the way the control works it is though the pane is expanding to show the text of the button. With your suggested approach it would like the items jump down on open.
I wonder if would be easier to have a fixed side pane with the controls laid out like you want and no hamburger button etc. This is not so unusual, the Settings app does it.
If you do go with a fixed width pane, I recommend looking at the XAML that defines the NavigationView control, which can be found inside C:\Program Files (x86)\Windows Kits\10\DesignTime\CommonConfiguration\Neutral\UAP\10.0.17763.0\Generic\generic.xaml
(according to the version of your SDK). Then you can make sure to use the theme resources used by the Windows so that your custom control has a similar look and feel.

Bootstrapper Application UI - How To move between pages

I am writing a Bootstrapper Application and want to create the UI for it using the WixStandardBootstrapperApplication. I want the UI such that on the first page(Install page), I see the standard EULA and a checkbox which says I accept and a button to proceed on the next page (Options page) which should get enabled only after I select the checkbox. On the next page, I list some text and want to have another checkbox, which kind of again says I accept and a button to Install which gets enabled only after I select the checkbox.
<Page Name="Install">
<Text X="154" Y="12" Width="-65" Height="21" DisablePrefix="yes">#(loc.Title)</Text>
<Image X="120" Y="20" Width="54" Height="325" ImageFile="logo.png"/>
<Richedit Name="EulaRichedit" X="154" Y="60" Width="-21" Height="-76" TabStop="yes" FontId="0" HexStyle="0x800000" />
<Checkbox Name="OptionsCheckbox" X="-11" Y="-41" Width="246" Height="17" TabStop="yes" FontId="3" HideWhenDisabled="yes">I accept.</Checkbox>
<Button Name="WelcomeCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.InstallCloseButton)</Button>
<Button Name="OptionsButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" Text="Proceed" HideWhenDisabled="yes">Next</Button>
</Page>
<Page Name="Options">
<Text X="185" Y="11" Width="-11" Height="32" FontId="1">#(loc.OptionsHeader)</Text>
<Image X="0" Y="0" Width="177" Height="325" ImageFile="logoside.png"/>
<Text X="180" Y="61" Width="-11" Height="17" FontId="3">Some text.</Text>
<Checkbox Name="EulaAcceptCheckbox" X="180" Y="251" Width="246" Height="17" TabStop="yes" FontId="3" HideWhenDisabled="yes">#(loc.OptionsButton)</Checkbox>
<Button Name="InstallButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" Text="Proceed">#(loc.InstallInstallButton)</Button>
<Button Name="OptionsCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.InstallCloseButton)</Button>
</Page>
The second page(Options page) is working according to what I need - Checkbox and Install button disabled, and it gets enabled only after selecting the checkbox. But on the first page(Install page) I am not able to make it work. The button is enabled even if the checkbox is not checked. I tried different options for the Checkbox and Button Name but I am unable to make it work. What can I do to make it work? Also if you have any link for any documentation for the different options then please share. I found the help file with Thmutil schema but it doesn't list the various options for Checkboxes or Buttons.
Any suggestions welcome. Feel free to ask if anything is unclear. Thanks for your help in advance.
To do this you'll need to delve into the code for your bootstrapperapplication (WixStdBootstrapperApplication.cpp).
Luckily you're basing this off of the WixStdBootstrapperApplication which I've spend quite some time getting to know.
First thing you need to do is put the EulaAcceptCheckbox back onto the page with the actual Eula on it. When you're going to control the UI elements being enabled/disabled you need to do this from within the bootstrapper application's code. The BA owns the UI.
Now we need to change the behaviour of that EulaAcceptCheckbox so that it enables/disables the OptionsButton.
In the WndProc is where we handle all the messages generated by the user when they click on a button or scroll or do anything. Under WM_COMMAND we have a switch based on LOWORD(wParam) which is the ID of the control that raised the message.
Locate "WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX" and see that it calls pBA->OnClickAcceptCheckbox();
Here is the method
void OnClickAcceptCheckbox()
{
BOOL fAcceptedLicense = ThemeIsControlChecked(m_pTheme, WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX);
ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_INSTALL_BUTTON, fAcceptedLicense);
}
Looks super simple right? Here you just have to change WIXSTDBA_CONTROL_INSTALL_BUTTON to the WIXSTDBA_CONTROL_OPTIONS_BUTTON
We also need to set the Options button to default disabled. To do this we go into "OnChangeState" and look for the if for WIXSTDBA_PAGE_INSTALL
if (m_rgdwPageIds[WIXSTDBA_PAGE_INSTALL] == dwNewPageId) // on the "Install" page, ensure the install button is enabled/disabled correctly.
{
LONGLONG llElevated = 0;
if (m_Bundle.fPerMachine)
{
BalGetNumericVariable(WIXBUNDLE_VARIABLE_ELEVATED, &llElevated);
}
ThemeControlElevates(m_pTheme, WIXSTDBA_CONTROL_INSTALL_BUTTON, (m_Bundle.fPerMachine && !llElevated));
// If the EULA control exists, show it only if a license URL is provided as well.
if (ThemeControlExists(m_pTheme, WIXSTDBA_CONTROL_EULA_LINK))
{
BOOL fEulaLink = (m_sczLicenseUrl && *m_sczLicenseUrl);
ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_EULA_LINK, fEulaLink);
ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX, fEulaLink);
}
BOOL fAcceptedLicense = !ThemeControlExists(m_pTheme, WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX) || !ThemeControlEnabled(m_pTheme, WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX) || ThemeIsControlChecked(m_pTheme, WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX);
ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_INSTALL_BUTTON, fAcceptedLicense);
// If there is an "Options" page, the "Options" button exists, and it hasn't been suppressed, then enable the button.
BOOL fOptionsEnabled = m_rgdwPageIds[WIXSTDBA_PAGE_OPTIONS] && ThemeControlExists(m_pTheme, WIXSTDBA_CONTROL_OPTIONS_BUTTON) && !m_fSuppressOptionsUI;
ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_OPTIONS_BUTTON, fOptionsEnabled);
// Show/Hide the version label if it exists.
if (m_rgdwPageIds[WIXSTDBA_PAGE_OPTIONS] && ThemeControlExists(m_pTheme, WIXSTDBA_CONTROL_VERSION_LABEL) && !m_fShowVersion)
{
ThemeShowControl(m_pTheme, WIXSTDBA_CONTROL_VERSION_LABEL, SW_HIDE);
}
}
We need to update this block to be
if (m_rgdwPageIds[WIXSTDBA_PAGE_INSTALL] == dwNewPageId) // on the "Install" page, ensure the install button is enabled/disabled correctly.
{
// If the EULA control exists, show it only if a license URL is provided as well.
if (ThemeControlExists(m_pTheme, WIXSTDBA_CONTROL_EULA_LINK))
{
BOOL fEulaLink = (m_sczLicenseUrl && *m_sczLicenseUrl);
ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_EULA_LINK, fEulaLink);
ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX, fEulaLink);
}
BOOL fAcceptedLicense = !ThemeControlExists(m_pTheme, WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX) || !ThemeControlEnabled(m_pTheme, WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX) || ThemeIsControlChecked(m_pTheme, WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX);
// If there is an "Options" page, the "Options" button exists, and it hasn't been suppressed, then enable the button.
BOOL fOptionsEnabled = m_rgdwPageIds[WIXSTDBA_PAGE_OPTIONS] && ThemeControlExists(m_pTheme, WIXSTDBA_CONTROL_OPTIONS_BUTTON) && !m_fSuppressOptionsUI;
ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_OPTIONS_BUTTON, fOptionsEnabled & fAcceptedLicense);
// Show/Hide the version label if it exists.
if (m_rgdwPageIds[WIXSTDBA_PAGE_OPTIONS] && ThemeControlExists(m_pTheme, WIXSTDBA_CONTROL_VERSION_LABEL) && !m_fShowVersion)
{
ThemeShowControl(m_pTheme, WIXSTDBA_CONTROL_VERSION_LABEL, SW_HIDE);
}
}
Here we removed the elevated stuff since that goes on the install button and instead enable/disable the options button depending on whether it is defined in the theme and if the accept checkbox is checked or not.
Next you'll need to add a way to locate your new OptionsPage checkbox.
You should have an enum in your cpp file
enum WIXSTDBA_CONTROL
It should be ordered into controls on pages. Here you'll need to add a new entry for your new Options checkbox control, maybe WIXSTDBA_CONTROL_OPTIONS_CHECKBOX
Below this enum you'll have a 2-d array
static THEME_ASSIGN_CONTROL_ID vrgInitControls[] =
You'll need to add a new entry here that is inserted at the same place you inserted into your enum. The inserted array item should look like this
{ WIXSTDBA_CONTROL_OPTIONS_CEHCKBOX, L"OptionsCheckbox" }, //The string should match the Name of the checkbox in the theme xml.
Now we need a way to handle messages from this Control. Head back to WndProc and add a new case to the switch under WM_COMMAND it should be
case WIXSTDBA_CONTROL_OPTIONS_CHECKBOX:
pBA->OnClickOptionsCheckbox();
return 0;
Now add a OnClickOptionsCheckbox method to your bootstrapper application just like the OnClickAcceptCheckbox()
void OnClickOptionsCheckbox()
{
BOOL fAccepted = ThemeIsControlChecked(m_pTheme, WIXSTDBA_CONTROL_OPTIONS_CHECKBOX);
ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_INSTALL_BUTTON, fAccepted);
}
Finally, we need to add the llElevated stuff we removed from the OnChangeState WIXSTDBA_PAGE_INSTALL case to WIXSTDBA_PAGE_OPTIONS and also set the default state of the Install button
else if (m_rgdwPageIds[WIXSTDBA_PAGE_OPTIONS] == dwNewPageId)
{
HRESULT hr = BalGetStringVariable(WIXSTDBA_VARIABLE_INSTALL_FOLDER, &sczUnformattedText);
if (SUCCEEDED(hr))
{
// If the wix developer is showing a hidden variable in the UI, then obviously they don't care about keeping it safe
// so don't go down the rabbit hole of making sure that this is securely freed.
BalFormatString(sczUnformattedText, &sczText);
ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_FOLDER_EDITBOX, sczText);
}
}
Will get changed to
else if (m_rgdwPageIds[WIXSTDBA_PAGE_OPTIONS] == dwNewPageId)
{
LONGLONG llElevated = 0;
if (m_Bundle.fPerMachine)
{
BalGetNumericVariable(WIXBUNDLE_VARIABLE_ELEVATED, &llElevated);
}
ThemeControlElevates(m_pTheme, WIXSTDBA_CONTROL_INSTALL_BUTTON, (m_Bundle.fPerMachine && !llElevated));
BOOL fAccepted = !ThemeControlExists(m_pTheme, WIXSTDBA_CONTROL_OPTIONS_CHECKBOX) || !ThemeControlEnabled(m_pTheme, WIXSTDBA_CONTROL_OPTIONS_CHECKBOX) || ThemeIsControlChecked(m_pTheme, WIXSTDBA_CONTROL_OPTIONS_CHECKBOX);
ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_INSTALL_BUTTON, fAccepted);
HRESULT hr = BalGetStringVariable(WIXSTDBA_VARIABLE_INSTALL_FOLDER, &sczUnformattedText);
if (SUCCEEDED(hr))
{
// If the wix developer is showing a hidden variable in the UI, then obviously they don't care about keeping it safe
// so don't go down the rabbit hole of making sure that this is securely freed.
BalFormatString(sczUnformattedText, &sczText);
ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_FOLDER_EDITBOX, sczText);
}
}
There are a few things I would still change around with this implementation but I would highly suggest trying to walk through what the bootstrapper application does and how it works.
If you want to change the behaviour of the UI during your install you'll need to get familiar with the code here. You can add new pages, add controls, and set variables along with some other stuff.
If this seems like a lot of work (figuring all this out myself definitely was) consider whether or not you really need this type of behaviour over the default behaviour of one of the default wixstdba themes.

A strange symptom about mvvmlight listbox SelectedIndex focused color after transition of pages

I have a question about Mvvmlight binding Listbox SelectedIndex.
The full source code can be downloaded here.
Here is my precondition:
[TestModel]
string Title;
string Description;
[TestViewModel]
ObservableCollection<TestModel> TestList;
[xaml binding]
<ListBox ItemSource="{Binding TestList}"
SelectedIndex="{Binding SelectedIndex Mode=TwoWay}">
.....
<i:EventTrigger EventName="SelectionChanged">
.....
</i:EventTrigger>.....
Here is my OnSelectionChanged code:
private void OnSelectionChanged(TestModel test)
{
int index = SelectedIndex;
Debug.WriteLine("[SelectionChanged] +++, index={0}", index);
// If selected index is -1 (no selection) do nothing
if (-1 == SelectedIndex)
return;
Debug.WriteLine("[SelectionChanged] selected item={0}", test.Title);
// Reset selected index to -1 (no selection)
SelectedIndex = -1;
Debug.WriteLine("[SelectionChanged] ---, index={0}", index);
}
I have a sample to have MainPage.xaml and TestPage.xaml.
MainPage: This page has a button, click the button will navigate to TestPage
TestPage: This page has a listbox and binding to ViewModel
When I run this sample, tap button to TestPage, and try to tap any item of Listbox, I can see the item has no focused color (because I reset SelectedIndex to -1).
Here comes the question, when I back to MainPage, then again tap button to TestPage, you will see tapping any item of Listbox will cause focused color on every item, it's strange.
Hope anyone can help me to see if any problem on my sample.
Thanks.
I got a workaround from somebody below:
Change:
<i:EventTrigger EventName="SelectionChanged">
To:
<i:EventTrigger EventName="Tap">
It really works as what I expected.
Tap can allow user to tap repeated ListItem, also "reset SelectedIndex = -1" can make selected item without highlight color.

Problem with ajax modal popup extender

I have a Button which is having modalpopupextender which is working absolutely fine no problem at all, but before the modalpopup appears i want to validated text box control if it is not valid then modalpopup should not appear other wise it should work as usual..
does anybody having idea.
We use following function. On the button click you can call this function. This will validate validation group that is passed to this function and it is work will pop the modal popup otherwise validation error will appear.
function ClientSideValidate(modalId,group)
{
var modal = $find(modalId);
Page_ClientValidate(group);
if(!Page_IsValid)
{
modal.show();
}
}
Something I've done in the past is manually show/hide the modal popup. I realize the ModalPopupExtender control requires a target, so you'll need a dummy target which will remain inactive:
<asp:LinkButton id="btnDummyTarget" runat="server" />
<asp:Button
id="btnActualButtonTiedToValidation"
ValidationGroup="SomeValidationGroup"
OnClick="MyButton_Click"
runat="server" />
<ajaxToolkit:ModalPopupExtender
id="mpeMyPopup"
PopupControlID="pnlSomePanelToShow"
TargetControlID="btnDummyTarget"
runat="server" />
Then, in your codebehind you can do the following:
protected void MyButton_Click(object sender, EventArgs e)
{
if(Page.IsValid)
mpeMyPopupExtender.Show();
}
This is also handy for delete confirmation dialogs.

Resources