How to do relative binding for button flyout in universal windows store app

廉价感情. 提交于 2019-12-12 02:07:47

问题


I want to bind my button flyout width and height with some other control but it not working

    <Grid >
        <Popup IsOpen="True" Name="popup">
            <Grid Name="popupBorder" Background="Red" Height="100" Width="100" >
            </Grid>
        </Popup>
        <Button Content="check flyout" Name="btn" Click="Button_Click" >
            <Button.Flyout>
                <Flyout>
                    <Border Name="flyoutBorder" Height="{Binding Path=Height, ElementName=popupBorder, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}" 
Width="{Binding Path=Width, ElementName=popupBorder, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}">
                    </Border>
                </Flyout>
            </Button.Flyout>
        </Button>
    </Grid>

I have also given datacontext to button but still same

DataContext="{Binding ElementName=localContext, Mode=OneWay}"

回答1:


When you bind data in the content of Flyout, the binding source is in Page, and binding target is in PopupRoot, they have different DataContext, so can't it work here.

Besides, a Flyout control is like this:

If you place a Border as Content of Flyout, it will be placed in the ScrollContentPresenter:

As you can see, if you set the Width and Height of content, it will not effect the size of the Flyout since there is a ScrollViewer inside it: ScrollViewer's content has unlimited height and width.

I want to bind my button flyout width and height with some other control but it not working

So, the right way to custom the size of Flyout is to style the FlyoutPresenter for example like this:

<Flyout>
    <Flyout.FlyoutPresenterStyle>
        <Style TargetType="FlyoutPresenter">
            <Setter Property="MinHeight" Value="100" />
            <Setter Property="MinWidth" Value="100" />
        </Style>
    </Flyout.FlyoutPresenterStyle>
    <Border Name="flyoutBorder" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
    </Border>
</Flyout>

Here we need to use MinHeight and MinWidth to set the size of Flyout, but since you want to bind Width and Height to some other control, and the Windows Runtime doesn't support a Binding usage for Setter.Value (the Binding won't evaluate and the Setter has no effect, you won't get errors, but you won't get the desired result either).

Usually when need data binding in Setter.Value, we can create some attached dependency properties. And to solve the different DataContext problem, we need to define the property in code behind or view model for example like this:

public static double NewWidth { get; set; } = 100.0;

Then bind the this property to the Width of popupBorder:

<Grid>
    <Popup IsOpen="False" Name="popup">
        <Grid Name="popupBorder" Background="Red" Height="100" Width="{Binding NewWidth}">
        </Grid>
    </Popup>
    <Button Content="check flyout" Name="btn" Click="Button_Click" Foreground="Black">
        <Button.Flyout>
            <Flyout>
                <Flyout.FlyoutPresenterStyle>
                    <Style TargetType="FlyoutPresenter">
                        <Setter Property="local:BindingBuilder.FlyoutWidth" Value="400" /> <!--This value has no meaning here, you can set it to any value.-->
                        <Setter Property="MinHeight" Value="100" />
                    </Style>
                </Flyout.FlyoutPresenterStyle>
                <Border Name="flyoutBorder" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
                </Border>
            </Flyout>
        </Button.Flyout>
    </Button>
</Grid>

To register attached property, you can for example code like this:

public class BindingBuilder : DependencyObject
{
    public static readonly DependencyProperty FlyoutWidthProperty =
        DependencyProperty.RegisterAttached("FlyoutWidth", typeof(double), typeof(BindingBuilder), new PropertyMetadata(0, OnFlyoutWidthChanged));

    public static double GetFlyoutWidth(DependencyObject obj)
    {
        return (double)obj.GetValue(FlyoutWidthProperty);
    }

    public static void SetFlyoutWidth(DependencyObject obj, double value)
    {
        obj.SetValue(FlyoutWidthProperty, value);
    }

    public static void OnFlyoutWidthChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        double newFlyoutWidth = (double)d.GetValue(FlyoutWidthProperty);
        var presenter = (FlyoutPresenter)d;
        presenter.MinWidth = MainPageViewModel.NewWidth;
    }
}

Here I only attached the MinWidth property, you can also use the same method to custom the MinHeight of FlyoutPresenter.



来源:https://stackoverflow.com/questions/39016307/how-to-do-relative-binding-for-button-flyout-in-universal-windows-store-app

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!