我的主页有appbar,它是在不同的页面共享。 我写了下面的代码打开一个GridView项的点击appbar。
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;
}
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>
但appbar没有弹出时,我选择gridview的项目。 有那么它真的玄无约束力的错误!
Answer 1:
没有绑定IsOpen属性的方式根据MSDN :
注意绑定到IsOpen
属性,因为没有预期结果PropertyChanged
当属性设置不会发生的通知。
Answer 2:
<AppBar Opened="AppBar_Opened" IsOpen="{Binding IsAppBarOpen, **Mode=TwoWay**}">
Answer 3:
这对我的作品。 我使用MVVM光工具包。
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}">
Answer 4:
罗马Weisert的答案正确地指出了可能的原因是没有工作,但同时也必须结合双向如扎克·韦纳建议(我不知道,因为结合了后者的原因是没有在目标TO-工作源方向反正)。 的当前值AppBar.IsOpen
可能不反映IsAppBarOpen
您的视图模型。 如果是这样的话,你尝试更新的价值,它可能是没有PropertyChanged
事件引发的,因为你实际上可能没有更新的值。 相反,你可能只是其值设置从false
到false
或true
到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,但是,我不建议你进一步头在(有罪)的方向。
Answer 5:
我有同样的问题,并使用卡利科技进行的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>
这就是在视图模型你的财产:
public bool AppBarsOpen
{
get { return _appBarsOpen; }
set
{
if (value.Equals(_appBarsOpen)) return;
_appBarsOpen = value;
NotifyOfPropertyChange(() => AppBarsOpen);
}
}
Answer 6:
有同样的问题,通过增加Closed事件,并从代码更新视图模型背后解决它。 认为没有别的办法,因为双向绑定是不工作作为罗马指出。
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#MainViewModel
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);
}
}
Answer 7:
你应该结合两者ISOPEN和IsSticky双向的,否则你将得到与具有挖掘两个时间取消选择的项目例题(一次可关闭应用程序栏和一次取消选择)以及它的将有助于让你的应用程序栏的行为更standarly(将防止应用栏当选择的项目弹出向下敲击)。
要显示应用栏,你需要做以下(顺序很重要):
this.IsAppBarSticky = true;
this.IsAppBarOpen = true;
而将其隐藏,请执行以下操作:
this.IsAppBarSticky = false;
this.IsAppBarOpen = false;
Answer 8:
另一种方式来完成这项工作,而不必使用代码隐藏处理程序应用程序栏关闭事件:
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;
}
文章来源: opening the appbar in metro style apps using binding property