0

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}"
Cherry Bu - MSFT
  • 10,160
  • 1
  • 10
  • 16
Rahul Sonone
  • 2,685
  • 1
  • 27
  • 38
  • Just a note, setting `UpdateSourceTrigger=PropertyChanged` has no effect in a one-way binding. It is also redundant to specify `Mode=OneWay`, because that is the default value anyway. Besides that, have you tried binding to the popupBorder's ActualWidth and ActualHeight? – Clemens Aug 18 '16 at 11:31
  • yes I have tried that also and I have to bind that only in but thats not working thats why I thought of binding width and height first – Rahul Sonone Aug 18 '16 at 11:45
  • localContext here is the name of the page. Name="localContext". – Rahul Sonone Aug 18 '16 at 11:46

1 Answers1

0

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:

enter image description here

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

enter image description here

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.

Grace Feng
  • 16,564
  • 2
  • 22
  • 45