Home > Software design >  Binding SizeChanged event to ViewModel
Binding SizeChanged event to ViewModel

Time:06-10

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

CodePudding user response:

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;
     }
  }

CodePudding user response:

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)
{
    //...
}
  • Related