2016-09-22 41 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