2017-09-14 9 views
0

私が望むものが可能かどうかは不明ですが、なぜそうではないかもわかりません。DependencyPropertyの値をViewModelプロパティに設定する

私はXAMLで定義した依存関係プロパティ(string)を持つユーザーコントロールを持っています。次のように:

<Window ... (EngraveUnitWindow) 
    DataContext = EngraveUnitViewModel 
    ... 
    ... 

    <parameters:DoubleParameterUserControl 
     DisplayName="Exchanger Offset [deg]" 
     DataContext="{Binding ExchangerOffset}"/> 

ビューモデル 'EngraveUnitViewModel':

public class EngraveUnitViewModel : ViewModelBase, IUnitViewModel 
    ... 
    ... 
    public DoubleParameterViewModel ExchangerOffset { get; } 

私が達成したい何、DoubleParameterViewModelDisplayNameParameterNameへのプロパティの値を設定されています。次のようにだから私はのviewmodelにDisplayNameをバインドStyleを作成しました:

<UserControl.Resources> 
    <Style TargetType="parameters:DoubleParameterUserControl"> 
     <Setter Property="DisplayName" Value="{Binding ParameterName, Mode=OneWayToSource}"/> 
    </Style> 
</UserControl.Resources> 

以下の完全なDoubleParameterUserControlコード:

<UserControl 
    ... 
    ... 
    d:DataContext="{d:DesignInstance viewModels:DoubleParameterViewModel, d:IsDesignTimeCreatable=False}" 
      Margin="5"> 

    <UserControl.Resources> 
     <Style TargetType="parameters:DoubleParameterUserControl"> 
      <Setter Property="DisplayName" Value="{Binding ParameterName, Mode=OneWayToSource}"/> 
     </Style> 
    </UserControl.Resources> 

    <Grid> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="300"/> 
      <ColumnDefinition Width="*"/> 
      <ColumnDefinition Width="Auto"/> 
     </Grid.ColumnDefinitions> 

     <TextBlock Grid.Column="0" Text="{Binding ElementName=DoubleParameter, Path=DisplayName}" VerticalAlignment="Center" Margin="5,0,0,0" /> 

     <Border Grid.Column="1" BorderThickness="1" BorderBrush="LightGray" Margin="0, 0, 5, 0"> 
      <TextBlock 
       VerticalAlignment="Center" 
       Text="{Binding Value, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" 
       Margin="5, 0, 5, 0"> 
       <TextBlock.InputBindings> 
        <MouseBinding Gesture="LeftClick" Command="{Binding ShowNumpadCommand}" /> 
       </TextBlock.InputBindings> 
      </TextBlock> 

     </Border> 
     <Button x:Name="_button" Grid.Column="2" MinWidth="30" MinHeight="30" Content="..." Command="{Binding ShowNumpadCommand}"/> 
    </Grid> 
</UserControl> 

そして背後にそのコードは(私が定義DependencyProp:

public partial class DoubleParameterUserControl 
{ 
    public string DisplayName 
    { 
     get => (string)GetValue(DisplayNameProperty); 
     set => SetValue(DisplayNameProperty, value); 
    } 

    public static readonly DependencyProperty DisplayNameProperty = 
     DependencyProperty.Register(nameof(DisplayName), typeof(string), typeof(DoubleParameterUserControl), 
      new PropertyMetadata("")); 

    public DoubleParameterUserControl() 
    { 
     InitializeComponent(); 

     _button.Focus(); 
    } 
} 

ビューモデル:

public class DoubleParameterViewModel : ViewModelBase 
{ 
    private readonly Parameter<double> parameter; 
    private double value; 

    public RelayCommand ShowNumpadCommand { get; } 

    public string ParameterName { get; set; } 

    public double Value 
    { 
     get => parameter.Value; 
     set 
     { 
      parameter.Value = value; 
      Set(() => Value, ref this.value, value); 
     } 
    } 

    public DoubleParameterViewModel(Parameter<double> parameter) 
    { 
     this.parameter = parameter; 

     ShowNumpadCommand = new RelayCommand(ShowNumpad); 
    } 

    private void ShowNumpad() 
    { 
     var numpadViewModel = new VirtualKeypadsViewModel(true) 
     { 
      ParameterName = ParameterName, 
      Input = Value.ToString("F2", CultureInfo.InvariantCulture) 
     }; 

     var numpad = new Numpad 
     { 
      Owner = System.Windows.Application.Current.MainWindow, 
      DataContext = numpadViewModel 
     }; 

     if (numpad.ShowDialog() == true) 
     { 
      Value = numpadViewModel.ResultAsDouble(); 
     } 
    } 
} 

ViewModelのプロパティParameterNameは決して設定されません。私のコードでは、タイトルバーにパラメータ名を表示するNumpadダイアログをポップアップしたいが、ParameterNameはバインドされたDisplayNameを受け取らなかった。

誰かが私にそれをどのように解決できるか説明してくれることを願っています。 (それは不可能で、それが悲しいことになるのであれば、なぜそうでないのでしょうか)

+0

'ExchangerOffset'何ですか?それは 'DoubleParameterViewModel'ですか? –

+0

VisualStudioの出力にSystem.Data.Errorがありますか? – sTrenat

+0

@EdPlunkettごめんなさい。私は質問を更新しました – bas

答えて

2

ShowNumpadCommandを実行するときにはDoubleParameterViewModel.ParameterNameが存在するようです。その場合は、プロパティを忘れて、コマンドパラメータとしてDisplayNameを渡すだけです。

public ICommand ShowNumpadCommand { get; } 

public DoubleParameterViewModel(Parameter<double> parameter) 
{ 
    this.parameter = parameter; 
    ShowNumpadCommand = new RelayCommand<string>(ShowNumpad); 
} 

private void ShowNumpad(string parameterName) 
{ 
    /* ... */ 
} 

Styleを取り除くと、その所有者のDisplayNameにあなたのボタンのコマンドパラメータをバインド:

<UserControl x:Name="EditorRoot"> 
    <!-- ... --> 
    <Button x:Name="_button" 
      Command="{Binding ShowNumpadCommand}" 
      CommandParameter="{Binding ElementName=EditorRoot, Path=DisplayName}" /> 
    <!-- ... --> 
</UserControl> 
+0

ああ私....それは華麗でした!魅力的な作品!ありがとう! – bas

+0

喜んで助けてください。あなたがこのソリューションに満足していれば、私はあなたの答えを受け入れることに感謝します。 –

+0

もう少し待つと思っていましたが、もっと多くの人が訪れるでしょう。まだ一度にあなたの修正をリファクタリングすると、私は成功を収めました。私は確かに答えを受け入れるでしょう – bas