具有属性绑定的自定义 UserControl 模板

Posted

技术标签:

【中文标题】具有属性绑定的自定义 UserControl 模板【英文标题】:Custom UserControl Template with Property-Binding 【发布时间】:2016-12-23 20:34:10 【问题描述】:

我创建了一个自定义的用户控件,其中包括一个椭圆和一个标签。椭圆的标签内容和颜色是绑定的: Binding-Properties 是 DependencyProperties。 Ellipse 的颜色取决于 Status,它是一个 bool(转换器创建颜色)

这是 UserControl1.xaml:

<UserControl x:Class="Plugin_UPS.Views.UserControl1"
  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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  xmlns:Converters="clr-namespace:WPF_Prism.Infrastructure.Converters.Ups;assembly=WPF_Prism.Infrastructure"
  mc:Ignorable="d"
  x:Name="UC1"
  d:DesignWidth="200" Height="40">

<UserControl.Resources>
    <ResourceDictionary>
        <Converters:BoolToColorConverter x:Key="BoolToColorConverter"/>
    </ResourceDictionary>
</UserControl.Resources>

<Grid x:Name="LayoutRoot" Height="42" Width="504">       
        <StackPanel HorizontalAlignment="Left" Margin="0,0,0,0" Height="Auto" Width="Auto" Grid.Column="0" Grid.Row="0">
            <Grid Height="Auto" Width="Auto" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="0,0,0,0" 
                          MinWidth="200" MaxWidth="200" MinHeight="35" MaxHeight="40">
                <Grid.RowDefinitions>
                    <RowDefinition Height="*" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="20" />
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>
                <Ellipse HorizontalAlignment="Left" VerticalAlignment="Center" Grid.Column="0" Grid.Row="0"
                                        Fill="Binding Status, Converter=StaticResource BoolToColorConverter, UpdateSourceTrigger=PropertyChanged"
                                        Height="15"
                                        Width="15"
                                        StrokeThickness="1"
                                        Stroke="Black">
                </Ellipse>
                <Label Content="Binding Text" Height="Auto" Width="Auto" Margin="0,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="16" Grid.Column="1" Grid.Row="0" />
            </Grid>
        </StackPanel>
</Grid>

</UserControl>

这是 UserControl1.xaml.cs:

namespace Plugin_UPS.Views

public partial class UserControl1 : UserControl

    public UserControl1()
    
        InitializeComponent();
    

    public string Text
    
        get  return (string)GetValue(TextProperty); 
        set  SetValue(TextProperty, value); 
    

    public static readonly DependencyProperty TextProperty =
        DependencyProperty.Register("Text", typeof(string), typeof(UserControl1));


    public bool Status
    
        get  return (bool)GetValue(StatusProperty); 
        set  SetValue(StatusProperty, value); 
    

    public static readonly DependencyProperty StatusProperty =
        DependencyProperty.Register("Status", typeof(bool), typeof(UserControl1));


这是我的 UPSViewModel.cs:

namespace Plugin_UPS.ViewModel

public class UPSViewModel
      
    public UPSViewModel()
    
    

    public string UpsModelText  get  return "Model";  

    private bool replaceBatteryCondition; 
    public bool ReplaceBatteryCondition  get  return replaceBatteryCondition;  set  replaceBatteryCondition = value;   
 

这是我的 UPSView.xaml: (这里我实现了UserControl1)

<UserControl x:Class="Plugin_UPS.Views.UPSView"
         x:Name="UPSUC"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
         xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
         xmlns:local="clr-namespace:Plugin_UPS"
         xmlns:Controls="clr-namespace:WPF_Prism.Controls.Controls;assembly=WPF_Prism.Controls"
         xmlns:ViewModel="clr-namespace:Plugin_UPS.ViewModel"
         xmlns:Views="clr-namespace:Plugin_UPS.Views"
         d:DataContext="d:DesignInstance ViewModel:UPSViewModel"
         mc:Ignorable="d" 
         d:DesignHeight="840" d:DesignWidth="1260">

        <Grid>

            <StackPanel>
                <Views:UserControl1 Margin="10,20,10,10" DataContext="Binding RelativeSource=RelativeSource Self" Text="Binding UpsModelText" Status="Binding ReplaceBatteryCondition"></Views:UserControl1>
            </StackPanel>

        </Grid>
</UserControl>

但是“状态”和“文本”的绑定不起作用。 (Status="True" 或 Text="Model" 正在工作)。

您知道问题可能是什么吗? 数据上下文有问题吗?

最好的问候 菲尔

【问题讨论】:

什么不完全有效?请进一步解释。这是你改变状态的时候吗?因为我们没有在你的 viewmodel 类中实现 INotifyPropertyChanged。 文本显示不工作。到目前为止,我不需要 NotifyProperty。我只想显示初始值。 【参考方案1】:

您不能像

那样将 UserControl 的 DataContext 设置为自身
DataContext="Binding RelativeSource=RelativeSource Self"

删除该分配并写入

<Views:UserControl1 Margin="10,20,10,10"
    Text="Binding UpsModelText"
    Status="Binding ReplaceBatteryCondition" />

现在您必须在 UserControl 的 XAML 中指定绑定的来源。

有多种方法可以做到这一点,其中一种是像这样设置 RelativeSource 属性:

<Label Content="Binding Text,
                 RelativeSource=RelativeSource AncestorType=UserControl" ... />

<Ellipse Fill="Binding Status,
                RelativeSource=RelativeSource AncestorType=UserControl,
                Converter=StaticResource BoolToColorConverter" ... />

请注意,在填充绑定上设置UpdateSourceTrigger=PropertyChanged 没有意义。

【讨论】:

非常感谢,就是这样。它工作完美。我也更改了问题中的代码,以便您拥有正确的代码。 我已恢复您对问题的编辑。答案对于修改后的问题没有意义。

以上是关于具有属性绑定的自定义 UserControl 模板的主要内容,如果未能解决你的问题,请参考以下文章

为啥在数据模板中使用 xaml UserControl 时无法绑定到依赖属性? [复制]

如何在 DataGridTemplateColumn 内的控件上双向绑定属性?

如何将 MainWindow 上的自定义属性放入 UserControl(来自 UserControl 库/DLL)?

Silverlight UserControl 自定义属性绑定

设置绑定到 WPF 用户控件内的自定义 DependencyProperty

将 Silverlight UserControl 自定义属性绑定到其元素