2012-09-25 33 views
1

我的主頁有appbar,它在不同的頁面上共享。我編寫了下面的代碼來打開一個gridview項目點擊的appbar。使用綁定屬性在metro風格應用中打開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> 

但是,當我選擇gridview項目時,appbar沒有彈出。沒有綁定錯誤,所以它真的很神祕!

+0

您可以發佈您的GridView和項目竊聽事件的定義是什麼? – Fixus

+0

你可以在你的xaml中添加DataContext嗎?也許你的約束是錯誤的。另一方面,我認爲你不應該這樣做,因爲不要指望在用戶界面中點擊時打開appbar。您想做什麼?當單擊右鍵或滑動時,AppBar將被調用。 –

+0

@Fixus我已經添加了gridview的定義。我認爲SelectionChangedEvent的工作原理與點擊對象相同?我嘗試了與右擊事件,但它沒有奏效。 – Bitsian

回答

1
<AppBar Opened="AppBar_Opened" IsOpen="{Binding IsAppBarOpen, **Mode=TwoWay**}"> 
+0

它的一個很好的建議,但奇怪的是它仍然不工作!! :( – Bitsian

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}"> 
3

沒有綁定IsOpen屬性according the msdn方式:

注意綁定到IsOpen屬性沒有預期的結果 因爲PropertyChanged通知時不會出現的 財產設置。

0

Roman Weisert的答案正確地指出了它不起作用的可能原因,儘管你也必須按照Zack Weiner的建議進行雙向綁定(我不確定後者的原因,因爲綁定不起作用無論如何在目標到源的方向)。當前值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方法與發揮出提高PropertyChanged事件簽名

void OnPropertyChanged([CallerMemberName] string propertyName = null) 

但是,我可以從您使用代碼隱藏的角度看到,您並不真正關注MVVM。如果MVVM不是您的問題,那麼您可以放棄IsAppBarOpen屬性,直接設置AppBar.IsOpen。然而,作爲一個信奉MVVM的人,我不建議你進一步朝那個(有罪的)方向前進。

0

我有同樣的問題,並使用卡利科技進行的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); 
    } 
} 
0

有同樣的問題,解決了它通過添加Closed事件並從後面的代碼更新ViewModel。由於TwoWay綁定不像羅曼指出的那樣工作,所以沒有別的辦法。

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

你應該結合兩者ISOPEN和IsSticky雙向的,否則你將得到與例如有問題點擊兩次以取消選擇一個項目(一次關閉應用程序欄,一次取消選擇)和這也將有助於讓您的應用欄更加標準化(防止應用欄在選擇某個項目時突然彈出)。
要顯示應用欄,你需要做以下(順序很重要):

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

,並隱藏它,請執行下列操作:

this.IsAppBarSticky = false; 
this.IsAppBarOpen = false; 
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; 
    } 
相關問題