opening the appbar in metro style apps using bindi

2019-08-01 20:09发布

My main page has the appbar and it is shared across different pages. I wrote the following code to open the appbar on the click of a gridview item.

XAML

<AppBar Opened="AppBar_Opened" IsOpen="{Binding IsAppBarOpen}">

Back end

private void Clock_SelectionChanged(object sender, SelectionChangedEventArgs e)
{            
    App.ViewModel.SelectedClock = (Clock)ThemeGridView.SelectedItem;
    App.WorldViewModel.IsAppBarOpen = true;                  
}

 private void ThemeGridView_ItemClick(object sender, ItemClickEventArgs e)
    {
        App.ViewModel.SelectedClock = (Clock)ThemeGridView.SelectedItem;
        App.WorldViewModel.IsAppBarOpen = true;
    } 

WorldViewModel

private bool _IsAppBarOpen;

public bool IsAppBarOpen
{
   get { return _IsAppBarOpen; }
   set { base.SetProperty(ref _IsAppBarOpen, value); }
}

GridView XAML

<GridView
        Grid.Row="1"
        Grid.Column="1"


         x:Name="ThemeGridView"                    
                ItemsSource="{Binding Clocks}" 
                ItemTemplate="{StaticResource WorldClockTemplate}"
                SelectionChanged="Clock_SelectionChanged"
                SelectionMode="None"
                IsItemClickEnabled="True"
                ItemClick="ThemeGridView_ItemClick"
                >
        <GridView.ItemsPanel>
            <ItemsPanelTemplate>
               <WrapGrid />
            </ItemsPanelTemplate>
        </GridView.ItemsPanel>
    </GridView>

But the appbar is not popping up when i select the gridview item. There is no binding error so its really mysterious!

8条回答
Rolldiameter
2楼-- · 2019-08-01 20:50

You should bind both IsOpen and IsSticky two way because otherwise you will get problems with for example having to tap two time to unselect an item (once to close the app bar and once for unselecting) and also it's the will help having your app bar behave more standarly (will prevent the app bar to pop down on tap when an item is selected).
To show the app bar you will need to do the following (the order is important):

this.IsAppBarSticky = true;
this.IsAppBarOpen = true;

and to hide it, do the following:

this.IsAppBarSticky = false;
this.IsAppBarOpen = false;
查看更多
Rolldiameter
3楼-- · 2019-08-01 20:51

Roman Weisert's answer correctly states the likely reason for it not working, although you also must make the binding two-way as Zack Weiner suggested (I'm not sure the reason for the latter since the binding is not working in the target-to-source direction anyway). The current value of AppBar.IsOpen may not be reflected by IsAppBarOpen of your view-model. When that's the case, and you try updating the value, it's possible that no PropertyChanged event is raised since you may not actually be updating a value. Instead, you may be just setting the value from false to false or from true to true. Most SetProperty method implementations do not raise the PropertyChanged event unless there is an actual change, and I presume yours is the same.

To fix the problem, consider modifying your view-model as follows:

public bool IsAppBarOpen
{
    get { return _IsAppBarOpen; } //changes initiated from UI not reflected
    set //not updated from UI
    {
        _IsAppBarOpen = value;
        base.OnPropertyChanged();
    }
}
bool _IsAppBarOpen;

The notable difference from your view-model's code, is that SetProperty is not called here so PropertyChanged is raised even when the backing store equals the newly introduced value. In case your base class differs, note that mine has an OnPropertyChanged method with the signature

void OnPropertyChanged( [CallerMemberName] string propertyName = null )

that serves to raise the PropertyChanged event.

I can see from your use of the code-behind, though, that you are not really following MVVM. If MVVM is not a concern to you, then you could forgo the IsAppBarOpen property altogether and just directly set AppBar.IsOpen. As someone who religiously adheres to MVVM, however, I do not recommend that you further head in that (sinful) direction.

查看更多
登录 后发表回答