【问题标题】:WPF UserControl PropertiesWPF 用户控件属性
【发布时间】:2014-08-01 19:00:42
【问题描述】:

在下面的代码中,我有一个包含椭圆和文本块的 UserControl。我想创建一个可以绑定的可重用控件,它允许我根据字符串设置文本,并根据布尔值更改红色/绿色之间的填充颜色。

我现在可以通过深入研究标记并使用一些复杂的绑定来做到这一点,但是我想在列表中重用这个控件,并且为此目的创建一个控件似乎更容易。但是,我不确定下一步该去哪里,是否应该创建与 FillText 的值相关的依赖属性,或者什么。

<UserControl
    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"
    mc:Ignorable="d"
    x:Class="Herp.Derp.View.DeliveryStatusIndicator"
    x:Name="UserControl"
    d:DesignWidth="91" d:DesignHeight="35">

    <Grid x:Name="LayoutRoot">
        <StackPanel  Orientation="Horizontal">
            <Ellipse Width="35" Height="35" Fill="Green">
                <Ellipse.OpacityMask>
                    <VisualBrush Stretch="Fill" Visual="{StaticResource appbar_location_circle}"/>
                </Ellipse.OpacityMask>
            </Ellipse>
            <TextBlock Style="{StaticResource Heading2}" 
                       VerticalAlignment="Center" Margin="3,0,0,0">
                 <Run Text="FRONT"/>
            </TextBlock>
        </StackPanel>
    </Grid>
</UserControl>

【问题讨论】:

  • 是的,在用户控件中创建依赖属性并从外部设置它们。在用户控件内部将控件绑定到自己的依赖属性

标签: c# wpf xaml controls dependency-properties


【解决方案1】:

是的,要创建“父”XAML 可以为其分配绑定的属性,您需要为要绑定到的每个字段创建一个DependencyProperty

然后,您将用户控件 xaml 绑定到 DP 的支持属性。

【讨论】:

    【解决方案2】:

    这里是如何实现的

    用户控制

    /// <summary>
    /// Interaction logic for UserControl1.xaml
    /// </summary>
    public partial class UserControl1 : UserControl
    {
        public UserControl1()
        {
            InitializeComponent();
        }
           public static readonly DependencyProperty FrontTextProperty = DependencyProperty.Register( "FrontText", typeof(string),typeof(UserControl1), new FrameworkPropertyMetadata(string.Empty));
        public string FrontText
        {
            get { return (string)GetValue(FrontTextProperty); }
            set {
                SetValue(FrontTextProperty, value);
                frontBlock.Text = value;  
            }
    
        }
        public static readonly DependencyProperty EllipseStateProperty = DependencyProperty.Register("EllipseState", typeof(bool), typeof(UserControl1), new FrameworkPropertyMetadata(false));
        public bool EllipseState
        {
            get { return (bool)GetValue(EllipseStateProperty); }
            set
            {
                SetValue(EllipseStateProperty, value);
                if (value)
                {
                    ellipse.Fill  = new SolidColorBrush( Colors.Green);  
                }
                else
                {
                    ellipse.Fill = new SolidColorBrush(Colors.Red);
                }
    
            }
    
        }
    
    
    }
    

    主窗口

    <Window
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:local="clr-namespace:WpfApplication1" x:Class="WpfApplication1.MainWindow"
            Title="MainWindow" Height="350" Width="525">
        <Grid>
    
            <local:UserControl1 EllipseState="{Binding yourProperty }"/>
            <CheckBox Content="CheckBox" HorizontalAlignment="Left" Margin="207,94,0,0" VerticalAlignment="Top"/>
    
        </Grid>
    </Window>
    

    【讨论】:

    • 看起来真的很接近,但是控件的 XAML 是否需要指向代码隐藏的 DP 的值?我尝试绑定到 MainWindow 中的 DP,它可以正常工作而没有错误或警告,但它不反映实际值(仅反映我在 XAML 中设置的默认值)
    • 我在您的帖子中添加了建议的编辑。如果它被接受,我会接受它作为答案。我现在意识到您不能直接从 DP 设置器更改 UI 元素。您需要在 DP 的注册中使用事件。
    • 抱歉,您建议的编辑被许多用户拒绝。但您可以尝试使用 TwoWayBinding 代替添加事件
    • 好吧,不幸的是,上面列出的代码不能完全工作。我有一个可行的解决方案,这很棒(再次感谢!)。我只是希望你提供它而不是我自己添加它。
    【解决方案3】:

    这是我得到的有效解决方案:

    public partial class DeliveryStatusIndicator : UserControl
    {
        public DeliveryStatusIndicator()
        {
                InitializeComponent();          
        }
    
        public static readonly DependencyProperty DeliveryDescriptionProperty = DependencyProperty.Register("DeliveryDescription", typeof(string), typeof(DeliveryStatusIndicator), new FrameworkPropertyMetadata("Default", DescriptionChangedEventHandler));
    
         private static void DescriptionChangedEventHandler(DependencyObject d, DependencyPropertyChangedEventArgs e)
         {
             ((DeliveryStatusIndicator)d).Desc.Text = (string)e.NewValue;
         }
    
         public string DeliveryDescription
         {
             get { return (string)GetValue(DeliveryDescriptionProperty); }
             set
             {
                 SetValue(DeliveryDescriptionProperty, value);
             }
    
         }
    
         public static readonly DependencyProperty DeliveryStatusProperty = DependencyProperty.Register("DeliveryStatus", typeof(bool), typeof(DeliveryStatusIndicator), new FrameworkPropertyMetadata(false, StatusChangedEventHandler));
    
         private static void StatusChangedEventHandler(DependencyObject d, DependencyPropertyChangedEventArgs e)
         {
             ((DeliveryStatusIndicator)d).Indicator.Fill = (bool)e.NewValue ? new SolidColorBrush(Colors.Green) : new SolidColorBrush(Colors.Red);
         }
    
         public bool DeliveryStatus
         {
             get { return (bool)GetValue(DeliveryStatusProperty); }
             set
             {
                 SetValue(DeliveryStatusProperty, value);
             }
         }
    

    }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-06
      相关资源
      最近更新 更多