2016-09-22 43 views
0

我有一個Flyout帶幫助器,以幫助綁定到確定其屬性的父元素。在Windows 10 UWP上使用StateTriggers綁定到另一個ElementName

,我努力調整該生產線是

helpers:FlyoutHelper.Parent="{Binding ElementName=appBarDelete}" 

它工作正常,在桌面上,但在Windows Mobile,我想綁定到不同的ElementName。有沒有辦法像條件綁定一樣創建一些東西,具體取決於它是在Mobile還是Desktop上運行?

我已經嘗試綁定到我的ViewModel中的字符串屬性,但助手抱怨,因爲它期望一個FrameworkElement。我認爲ElementName可以是任何字符串,也許有一個內部轉換器將該字符串轉換爲其FrameworkElement

任何想法?

<AppBarButton x:Name="menuZoom" Label="Thumbnail Size" > 
    <FlyoutBase.AttachedFlyout> 
     <Flyout x:Name="flyOut" helpers:FlyoutHelper.IsOpen="{Binding IsOpen, Mode=TwoWay}" helpers:FlyoutHelper.Parent="{Binding ElementName=appBarDelete}"> 
      <StackPanel Width="240"> 
       <TextBlock Text="Desired Size"/> 
       <Slider Minimum="50" Maximum="500" Value="{Binding ImageDesiredWidth, Mode=TwoWay}" /> 
       <Button Content="OK" Command="{Binding CloseCommand}" HorizontalAlignment="Right" /> 
      </StackPanel> 
     </Flyout> 
    </FlyoutBase.AttachedFlyout> 

這裏是我的FloutHelper

public static class FlyoutHelper 
{ 
    public static readonly DependencyProperty IsVisibleProperty = 
     DependencyProperty.RegisterAttached(
     "IsOpen", typeof(bool), typeof(FlyoutHelper), 
     new PropertyMetadata(true, IsOpenChangedCallback)); 

    public static readonly DependencyProperty ParentProperty = 
     DependencyProperty.RegisterAttached(
     "Parent", typeof(FrameworkElement), typeof(FlyoutHelper), null); 

    public static void SetIsOpen(DependencyObject element, bool value) 
    { 
     element.SetValue(IsVisibleProperty, value); 
    } 

    public static bool GetIsOpen(DependencyObject element) 
    { 
     return (bool)element.GetValue(IsVisibleProperty); 
    } 

    private static async void IsOpenChangedCallback(DependencyObject d, 
     DependencyPropertyChangedEventArgs e) 
    { 
     var fb = d as FlyoutBase; 
     if (fb == null) 
      return; 

     if ((bool)e.NewValue) 
     { 
      try 
      { 
       fb.Closed += flyout_Closed; 
       fb.ShowAt(GetParent(d)); 
      } 
      catch (Exception msg) 
      { 
       var dialog = new MessageDialog(msg.Message); 
       await dialog.ShowAsync(); 
      } 

     } 
     else 
     { 
      fb.Closed -= flyout_Closed; 
      fb.Hide(); 
     } 
    } 

    private static void flyout_Closed(object sender, object e) 
    { 
     // When the flyout is closed, sets its IsOpen attached property to false. 
     SetIsOpen(sender as DependencyObject, false); 
    } 

    public static void SetParent(DependencyObject element, FrameworkElement value) 
    { 
     element.SetValue(ParentProperty, value); 
    } 

    public static FrameworkElement GetParent(DependencyObject element) 
    { 
     return (FrameworkElement)element.GetValue(ParentProperty); 
    } 
} 

更新

我已經成功地從後面用下面的代碼中設置的Parent屬性。

private void setFlyoutParent() 
{ 
    if (DeviceTypeHelper.GetDeviceFormFactorType() == DeviceFormFactorType.Phone) 
    { 
     FlyoutHelper.SetParent(this.flyOut, this.appBarPath); 
    } 
    else 
    { 
     FlyoutHelper.SetParent(this.flyOut, this.appBarDelete); 
    } 
} 

這工作正常,但我想用VisualState.StateTriggers並設置MinWindowWidth

回答

0

AdaptiveTrigger

財產當你更新的問題,還可以使用AdaptiveTrigger做什麼你需要。因爲FlyoutHelper.ParentProperty是附加屬性,則需要使用括號來設置它是這樣的:

<VisualState> 
    <VisualState.StateTriggers> 
     <AdaptiveTrigger MaxWindowWidth="..." /> 
    </VisualState.StateTriggers> 
    <VisualState.Setters> 
     <Setter Target="flyOut.(helpers:FlyoutHelper.Parent)" 
       Value="{Binding ElementName=theElementOnMobile}" /> 
    </VisualState.Setters> 
</VisualState> 

備選方案 - 代碼

最簡單的解決辦法是做在的代碼隱藏頁。在構造函數中,後InitializeComponent呼叫添加以下內容:

if (AnalyticsInfo.VersionInfo.DeviceFamily.Contains("Mobile")) 
{ 
    flyOut.SetValue(FlyoutHelper.ParentProperty, theElementOnMobile); 
} 
else 
{ 
    flyOut.SetValue(FlyoutHelper.ParentProperty, appBarDelete); 
} 

爲了使這種清潔劑,可以使用通過Template 10提供的DeviceUtils - see on GitHub。有了這個,你可以簡化代碼:

flyOut.SetValue(FlyoutHelper.ParentProperty, 
    DeviceUtils.CurrentDeviceFamily == DeviceFamilies.Mobile ? 
     theElementOnMobile : appBarDelete); 
+0

謝謝@MZetko。我發現這是可能的。但是,我稍微改變了這個問題。我想在'StateTriggers'上做。查看更新的問題。謝謝。 – PutraKg

+0

我試過了你的建議,但是得到一個'DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION',帶有'災難性故障'的信息。我嘗試創建一個Public'Parent'屬性。 '公共FrameworkElement父 {返回(FrameworkElement)GetValue(ParentProperty); } set {SetValue(ParentProperty,value);} }但VisualStudio抱怨'GetValue'和'SetValue'在當前上下文中不存在。 – PutraKg

+0

也許我需要創建一個繼承'Flyout'的UserControl? – PutraKg