不知道我想要的是否可能,但我也不知道它为什么不是。将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; }
我想达到的目标,是集DisplayName
到ParameterName
财产在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。
我希望有人能解释我如何解决这个问题。 (或者说,这是不可能的,以及为什么不这样做,如果可悲的情况下)
什么'ExchangerOffset'?那是'DoubleParameterViewModel'吗? –
您的VisualStudio输出中是否有任何System.Data.Error? – sTrenat
@EdPlunkett对不起,错过了一个,是的,这是正确的。我更新了这个问题 – bas