2017-09-14 219 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; } 

我想達到的目標,是集DisplayNameParameterName財產在DoubleParameterViewModel價值。所以,我創建了一個Style結合的DisplayName到視圖模型如下:

<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

看起來像DoubleParameterViewModel.ParameterName存在只提供一個名稱,當執行ShowNumpadCommand。如果是這種情況,請忘記該屬性,並將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