[WPF] DP에서 ViewModel로 데이터 전송

노하우를 여쭙니다.

현재 저의 상황은 MainWindow.xaml에 UserControl이 2개 있고, 그 UserControl이 같은 UI 레벨에 있는 Slider의 Value를 참조하고자 하여 아래와 같이 했습니다.

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="20"/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Slider Name="MySlider" 
                HorizontalAlignment="Left" 
                VerticalAlignment="Bottom" 
                Width="1200" 
                Minimum="0" 
                Maximum="100"
                IsSnapToTickEnabled="True"
                TickFrequency="1"
                Grid.Row="0">
            <dxmvvm:Interaction.Behaviors>
                <dxmvvm:EventToCommand EventName="ValueChanged"
                                       Command="{Binding SliderValueChangedCommand}"
                                       CommandParameter="{Binding ElementName=MySlider, Path=Value}"/>
            </dxmvvm:Interaction.Behaviors>
        </Slider>
        <local:PTProgressBarVM Grid.Row="1"
                               ProgressValue="{Binding ElementName=MySlider, Path=Value}"/>
        <local:PTProgressBarWipe Grid.Row="2"
                                 ProgressValue="{Binding ElementName=MySlider, Path=Value}"/>
        <!--<local:PTProgressBar Grid.Row="1"/>-->
        <!--<local:PTProgressBarOpenCV Grid.Row="1"/>-->
    </Grid>

이렇게 각 PTProgressBarVM, PTProgressBarWipe UserControl에서 DP(ProgressValue)에 Slider의 Value를 바인딩한 다음,

각각의 UserControl에서는 DP에 바인딩된 값을 자기자신과 바인딩된 ViewModel에 넘겨주고 싶습니다.

이런 경우 어떤식으로하면 WPF스럽고 깔끔하게 할 수 있을까요?

제가 해본 것은 dxmvvm에 있는 Messenger를 통해 ViewModel로 값을 넘겨주는 것들인데, 이런 것 말고 좀 xaml이나 wpf에 의존적인 기능으로 처리하고 싶어서 여쭤봅니다.
그래서 일부러 DP를 사용했습니다.

2개의 좋아요

@Vincent DependencyProperty를 만드셨다면 ICommand도 추가해서
마치 Button의 Command 처럼 ViewModel에서 활용할 수도 있겠네요!

의도하시는게 이게 맞는건지는 정확치가 않네요. :sweat_smile:

MainWindow

<PTProgressBarVM ProgressValue="{Binding ElementName=MySlider, Path=Value}"/>

Control

class PTProgressBarVM : Control
{
    public static readonly DependencyProperty ProgressCommandProperty = 
        DependencyProperty.Register(
            "ProgressCommand", 
            typeof(ICommand), 
            typeof(PTProgressBarVM));

    public static readonly DependencyProperty PasswordProperty =
        DependencyProperty.Register(
            "ProgressValue", 
            typeof(double), 
            typeof(PTProgressBarVM),
            new PropertyMetadata(0.0, ProgressValueChanged));
        
    public ICommand ProgressCommand
    {
        get { return (ICommand)this.GetValue(ProgressCommandProperty); }
        set { this.SetValue(ProgressCommandProperty, value); }
    }

    public doubleProgressValue
    {
        get { return (double)this.GetValue(ProgressValueProperty); }
        set { this.SetValue(ProgressValueProperty, value); }
    }
    
    private static void ProgressValueChanged(
        DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var control = (PTProgressBarVM)d;
        control.ProgressCommand?.Invoke(e.NewValue);
    }
}

ViewModel

class PTProgressBarVIewModel
{
    public ICommand ProgressValueCommand { get; }
    ...
}
2개의 좋아요