1

我的主页有 appbar,它在不同的页面之间共享。我编写了以下代码以在单击 gridview 项目时打开应用程序栏。

XAML

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

后端

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;
    } 

世界观模型

private bool _IsAppBarOpen;

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

网格视图 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>

但是当我选择 gridview 项目时,appbar 没有弹出。没有绑定错误,所以它真的很神秘!

4

8 回答 8

3

没有办法根据 msdn绑定 IsOpen 属性:

注意 绑定到IsOpen属性没有预期的结果,因为PropertyChanged设置属性时不会发生通知。

于 2012-12-30T03:08:56.017 回答
1
<AppBar Opened="AppBar_Opened" IsOpen="{Binding IsAppBarOpen, **Mode=TwoWay**}">
于 2012-10-10T13:30:58.387 回答
1

这对我有用。我使用 MVVM Light Toolkit。

public bool AppBarIsOpen
{
    get { return this._appBarIsOpen; }

    set
    {
        if (this._appBarIsOpen == value) { return; }

        this._appBarIsOpen = value;
        this.RaisePropertyChanged("AppBarIsOpen"); // without INotifyPropertyChanged it doesn't work
    }
}


<AppBar
    IsSticky="True"
    IsOpen="{Binding Path=AppBarIsOpen, Mode=TwoWay}">
于 2012-11-05T19:20:32.960 回答
0

无需为应用栏关闭事件使用代码隐藏处理程序即可完成这项工作的另一种方法:

public class AppBarClosedCommand
{
    public static readonly DependencyProperty CommandProperty = DependencyProperty.RegisterAttached("Command", typeof(ICommand),
        typeof(AppBarClosedCommand), new PropertyMetadata(null, CommandPropertyChanged));


    public static void SetCommand(DependencyObject attached, ICommand value)
    {
        attached.SetValue(CommandProperty, value);
    }


    public static ICommand GetCommand(DependencyObject attached)
    {
        return (ICommand)attached.GetValue(CommandProperty);
    }


    private static void CommandPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        // Attach click handler
        (d as AppBar).Closed += AppBar_onClose;
    }


    private static void AppBar_onClose(object sender, object e)
    {
        // Get GridView
        var appBar = (sender as AppBar);


        // Get command
        ICommand command = GetCommand(appBar);


        // Execute command
        command.Execute(e);
    }
}

然后在 XAML 中你可以像这样使用它:

common:AppBarClosedCommand.Command="{Binding AppBarClosedCommand}"

命令功能如下所示:

public void OnAppBarClosed()
    {
        AppBarOpen = false;
    }
于 2014-01-30T15:29:23.587 回答
0

您应该以两种方式绑定 IsOpen 和 IsSticky ,否则您将遇到问题,例如必须点击两次以取消选择项目(一次关闭应用栏,一次取消选择),这将有助于您的应用栏表现更明显(将在选择项目时阻止App Bar弹出点击)。
要显示应用栏,您需要执行以下操作(顺序很重要):

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

并隐藏它,请执行以下操作:

this.IsAppBarSticky = false;
this.IsAppBarOpen = false;
于 2013-09-15T16:42:34.907 回答
0

有同样的问题,通过添加 Closed 事件并从后面的代码更新 ViewModel 来解决它。由于 TwoWay 绑定没有像 Roman 指出的那样工作,所以没有其他方法。

XAML

<AppBar x:Name="BottomAppBar1"
                AutomationProperties.Name="Bottom App Bar"
                Closed="BottomAppBar1_Closed"
                IsOpen="{Binding IsOpen, Mode=TwoWay}"
                IsSticky="True">

后面的 C# 代码

private void BottomAppBar1_Closed(object sender, object e)
{
  MainViewModel vm = this.DataContext as MainViewModel;
  vm.IsOpen = false;
}

C# 主视图模型

public const string IsOpenPropertyName = "IsOpen";

private bool isOpen = false;

/// <summary>
/// Sets and gets the IsOpen property.
/// Changes to that property's value raise the PropertyChanged event. 
/// </summary>
public bool IsOpen
{
  get
  {
    return isOpen;
  }
  set
  {
    RaisePropertyChanging(IsOpenPropertyName);
    isOpen = value;
    RaisePropertyChanged(IsOpenPropertyName);
  }
}
于 2013-09-14T23:17:41.507 回答
0

Roman Weisert 的回答正确地说明了它不起作用的可能原因,尽管您还必须按照 Zack Weiner 的建议进行双向绑定(我不确定后者的原因,因为绑定在目标到 -无论如何来源方向)。您的视图模型AppBar.IsOpen可能无法反映的当前值。IsAppBarOpen在这种情况下,您尝试更新值时,可能不会PropertyChanged引发任何事件,因为您实际上可能并未更新值。相反,您可能只是将值设置为 from falsetofalse或 from trueto true。除非有实际更改,否则大多数SetProperty方法实现不会引发事件,我认为您的方法是相同的。PropertyChanged

要解决此问题,请考虑按如下方式修改您的视图模型:

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

与您的视图模型代码的显着区别在于,即使在后备存储等于新引入的值时,也会在SetProperty此处调用它。PropertyChanged如果您的基类不同,请注意我的有一个OnPropertyChanged带有签名的方法

void OnPropertyChanged( [CallerMemberName] string propertyName = null )

这有助于引发PropertyChanged事件。

但是,从您对代码隐藏的使用中,我可以看出您并没有真正遵循 MVVM。如果您不关心 MVVM,那么您可以IsAppBarOpen完全放弃该属性并直接设置AppBar.IsOpen. 然而,作为一个虔诚地坚持 MVVM 的人,我不建议你进一步朝那个(有罪的)方向前进。

于 2013-07-23T15:53:15.677 回答
0

我遇到了同样的问题,并且将 Caliburn Micro 用于 WinRT,并且这段代码对我有用:

<AppBar IsOpen="{Binding AppBarsOpen}" Name="MainAppBar" Padding="10,0,10,0" AutomationProperties.Name="Bottom App Bar">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="50*" />
            <ColumnDefinition Width="50*" />
        </Grid.ColumnDefinitions>
        <StackPanel x:Name="LeftPanel" Orientation="Horizontal" Grid.Column="0" HorizontalAlignment="Left">
            <Button Name="ShowFlyout"  Style="{StaticResource BookmarksAppBarButtonStyle}" />
        </StackPanel>
        <StackPanel x:Name="RightPanel" Orientation="Horizontal" Grid.Column="1" HorizontalAlignment="Right">
            <Button Style="{StaticResource SaveAppBarButtonStyle}" />
        </StackPanel>
    </Grid>
</AppBar>

这就是您在 ViewModel 中的属性:

public bool AppBarsOpen
{
    get { return _appBarsOpen; }
    set
    {
        if (value.Equals(_appBarsOpen)) return;
        _appBarsOpen = value;
        NotifyOfPropertyChange(() => AppBarsOpen);
    }
}
于 2013-09-09T13:39:27.513 回答