如何在 WPF 中使用 Caliburn.Micro 和 UserControl 的绑定?
How to use binding in WPF with Caliburn.Micro and with UserControl?
我创建了一个带有一些字段的用户控件。我想使用它并将数据绑定到这些字段。其中大部分是静态值,但 DataValue
属性 来自 MainView 的一个 属性。
我的代码:
DataDisplayer.xaml
<UserControl x:Class="TabletMachineAccess.Controls.DataDisplayer"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:TabletMachineAccess.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Name="dataDisplayer"
MaxHeight="100"
mc:Ignorable="d">
<Border Height="auto"
Margin="5"
Padding="5,2,5,2"
BorderBrush="Gray"
BorderThickness="2"
CornerRadius="5">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding DataType}" />
<TextBlock Text=":" />
</StackPanel>
<Separator Style="{StaticResource BasicSeparator}" />
<TextBlock Margin="0,0,0,0"
HorizontalAlignment="Center"
FontWeight="Bold"
Text="{Binding Path=DataValue,
ElementName=dataDisplayer}" />
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
<TextBlock FontWeight="ExtraLight" Text="(" />
<TextBlock FontWeight="ExtraLight" Text="{Binding UnitText}" />
<TextBlock FontWeight="ExtraLight" Text=")" />
</StackPanel>
</StackPanel>
</Border>
</UserControl>
DataDisplayer.xaml.cs
public partial class DataDisplayer : UserControl
{
public double DataValue
{
get { return (double)GetValue(DataValueProperty); }
set { SetValue(DataValueProperty, value); }
}
// Using a DependencyProperty as the backing store for DataValue. This enables animation, styling, binding, etc...
public static readonly DependencyProperty DataValueProperty =
DependencyProperty.Register("DataValue", typeof(double), typeof(DataDisplayer), new PropertyMetadata(9.9));
public string DataType
{
get; set;
}
public string UnitText
{
get; set;
}
public DataDisplayer()
{
InitializeComponent();
this.DataContext = this;
}
}
我尝试在 MainView.xaml 中这样使用它
<controls:DataDisplayer Grid.Row="1"
Grid.Column="0"
DataType="{x:Static res:Strings.PVUpper}"
DataValue="{Binding PVUpper}"
UnitText="{x:Static res:Strings.KgUnit}" />
我的 MainViewModel.cs 里有这个
public double PVUpper { get; set; }
对于那些从 res:Strings
获取数据的属性可以正常工作并显示正确的值,但 DataValue
属性 始终显示 DependencyProperty (9.9) 的默认值。 PVUpper
的值在 ViewModel 中每秒都在变化,所以我希望在 View 上也能看到这种变化。
问题是绑定的 DataContex 错误。您将 DataDisplayer
的 DataContext
-属性 设置为自身
public DataDisplayer()
{
InitializeComponent();
this.DataContext = this;
}
因此绑定 DataValue="{Binding PVUpper}"
试图在您的 DataDisplayer
实例上找到名称为 PVUpper
的 属性,这当然不会成功。
所以你不应该做 this.DataContext = this;
而只是让 DataContext
保持不变(你的控件将继承其父控件的数据上下文)。
您还需要更改 DataDisplayer.xaml
中的绑定以解决更改后的 DataContext。
但是您可以简单地向所有绑定添加一个 ElementName=dataDisplayer
以绑定到您的 DataDisplayer
实例。
例如
<TextBlock FontWeight="ExtraLight" Text="{Binding UnitText}" />
变成
<TextBlock FontWeight="ExtraLight" Text="{Binding UnitText, ElementName=dataDisplayer}" />
我创建了一个带有一些字段的用户控件。我想使用它并将数据绑定到这些字段。其中大部分是静态值,但 DataValue
属性 来自 MainView 的一个 属性。
我的代码:
<UserControl x:Class="TabletMachineAccess.Controls.DataDisplayer"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:TabletMachineAccess.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Name="dataDisplayer"
MaxHeight="100"
mc:Ignorable="d">
<Border Height="auto"
Margin="5"
Padding="5,2,5,2"
BorderBrush="Gray"
BorderThickness="2"
CornerRadius="5">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding DataType}" />
<TextBlock Text=":" />
</StackPanel>
<Separator Style="{StaticResource BasicSeparator}" />
<TextBlock Margin="0,0,0,0"
HorizontalAlignment="Center"
FontWeight="Bold"
Text="{Binding Path=DataValue,
ElementName=dataDisplayer}" />
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
<TextBlock FontWeight="ExtraLight" Text="(" />
<TextBlock FontWeight="ExtraLight" Text="{Binding UnitText}" />
<TextBlock FontWeight="ExtraLight" Text=")" />
</StackPanel>
</StackPanel>
</Border>
</UserControl>
DataDisplayer.xaml.cs
public partial class DataDisplayer : UserControl
{
public double DataValue
{
get { return (double)GetValue(DataValueProperty); }
set { SetValue(DataValueProperty, value); }
}
// Using a DependencyProperty as the backing store for DataValue. This enables animation, styling, binding, etc...
public static readonly DependencyProperty DataValueProperty =
DependencyProperty.Register("DataValue", typeof(double), typeof(DataDisplayer), new PropertyMetadata(9.9));
public string DataType
{
get; set;
}
public string UnitText
{
get; set;
}
public DataDisplayer()
{
InitializeComponent();
this.DataContext = this;
}
}
我尝试在 MainView.xaml 中这样使用它
<controls:DataDisplayer Grid.Row="1"
Grid.Column="0"
DataType="{x:Static res:Strings.PVUpper}"
DataValue="{Binding PVUpper}"
UnitText="{x:Static res:Strings.KgUnit}" />
我的 MainViewModel.cs 里有这个
public double PVUpper { get; set; }
对于那些从 res:Strings
获取数据的属性可以正常工作并显示正确的值,但 DataValue
属性 始终显示 DependencyProperty (9.9) 的默认值。 PVUpper
的值在 ViewModel 中每秒都在变化,所以我希望在 View 上也能看到这种变化。
问题是绑定的 DataContex 错误。您将 DataDisplayer
的 DataContext
-属性 设置为自身
public DataDisplayer() { InitializeComponent(); this.DataContext = this; }
因此绑定 DataValue="{Binding PVUpper}"
试图在您的 DataDisplayer
实例上找到名称为 PVUpper
的 属性,这当然不会成功。
所以你不应该做 this.DataContext = this;
而只是让 DataContext
保持不变(你的控件将继承其父控件的数据上下文)。
您还需要更改 DataDisplayer.xaml
中的绑定以解决更改后的 DataContext。
但是您可以简单地向所有绑定添加一个 ElementName=dataDisplayer
以绑定到您的 DataDisplayer
实例。
例如
<TextBlock FontWeight="ExtraLight" Text="{Binding UnitText}" />
变成
<TextBlock FontWeight="ExtraLight" Text="{Binding UnitText, ElementName=dataDisplayer}" />