简体   繁体   中英

Binding SizeChanged event to ViewModel

My xaml code:

            <Grid>
                <Interactivity:Interaction.Behaviors>
                    <Interactions:EventTriggerBehavior EventName="SizeChanged">
                        <Interactions:InvokeCommandAction Command="{Binding OnSizeChanged}"/>
                    </Interactions:EventTriggerBehavior
            </Grid>

In ViewModel:

public IRelayCommand OnSizeChanged => new RelayCommand(SizeChangedEvent);
private void SizeChangedEvent()
{
     // How to receive width and height at here
}

So my question is how to receive with and height in View model?

Thanks

You could use the CommandParameter property and value converter.

XAML:

<Grid x:Name="grid">
    <Interactivity:Interaction.Behaviors>
        <Interactions:EventTriggerBehavior EventName="SizeChanged">
            <Interactions:InvokeCommandAction Command="{Binding OnSizeChanged}">
                <Interactions:InvokeCommandAction.CommandParameter>
                    <Binding ElementName="grid">
                        <Binding.Converter>
                            <local:SizeConverter />
                        </Binding.Converter>
                    </Binding>
                </Interactions:InvokeCommandAction.CommandParameter>
            </Interactions:InvokeCommandAction>
        </Interactions:EventTriggerBehavior>
    </Interactivity:Interaction.Behaviors>
</Grid>

Converter:

public class SizeConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language) =>
        value is FrameworkElement fe ? (fe.ActualWidth, fe.ActualHeight) : (double.NaN, double.NaN);

    public object ConvertBack(object value, Type targetType, object parameter, string language) =>
        throw new NotSupportedException();
}

View Model:

public IRelayCommand OnSizeChanged => new RelayCommand<(double, double)>(SizeChangedEvent);

private void SizeChangedEvent((double width, double height) size)
{
    //...
}

Canvas cant have sizechanged event because Canvas uses absolute positioning as its layout technique for its contained child elements. As stated in the document

Because absolute positioning does not take into account the size of the app window, scaling, or other user-selected sizing, using a container element that adapts to different orientations and screen settings, such as Grid or StackPanel, is often a better choice than using Canvas. For more information, see Define layouts with XAML.

Edit: (based on comment)

For Grid you could directly bind the sizechanged event to the eventhandler in ViewModel like the example below

Xaml

<Grid SizeChanged="{x:Bind viewModel.Grid_SizeChanged,Mode=OneWay}">
</Grid> 

Xaml.cs

  ViewModel viewModel { get; set; } = new ViewModel();
  public MainPage()
  {
      this.InitializeComponent();
  }

ViewModel.cs

  public class ViewModel
  {
     public void Grid_SizeChanged(object sender, SizeChangedEventArgs e)
     {
          var height = (sender as Grid).ActualHeight;
     }
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM