【问题标题】:WPF. Setting dependency properties of custom controlsWPF。设置自定义控件的依赖属性
【发布时间】:2014-05-22 19:45:30
【问题描述】:

我知道已经回答了很多关于依赖属性的问题,但我读过的问题都没有解决我的问题,所以这里是。

我有一个带有按钮和文本块的简单用户控件。文本块包含一个我希望能够从包含控件的窗口或视图中设置的数字。我还需要能够通过按下控件中的按钮来增加值。

这是我的主窗口:

    <Window x:Class="DependencyPropertiesTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
        xmlns:local="clr-namespace:DependencyPropertiesTest">
    <Grid>
        <StackPanel Width="200" VerticalAlignment="Center">
            <local:UserControl1 Margin="10" UserControlNumber="{Binding Number}"/>
            <TextBlock Text="{Binding Number}" Margin="10"/>
            <Button Content="n" Click="Button_Click" Margin="10"/>
        </StackPanel>
    </Grid>
</Window>

背后的代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace DependencyPropertiesTest
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;
            Number = 1;
        }

        private int number;
        public int Number
        {
            get { return number; }
            set
            {
                number = value;
                OnPropertyChanged("Number");
            }
        }


        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Number++;
        }
    }
}

这是我的自定义控件:

    <UserControl x:Class="DependencyPropertiesTest.UserControl1"
             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" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <Viewbox HorizontalAlignment="Center" VerticalAlignment="Center" Height="40" Width="100">
            <Border BorderBrush="Black" BorderThickness="1">
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding UserControlNumber, TargetNullValue='nn',  FallbackValue='ff'}" Margin="5"/>
                    <Button Content="+" Margin="5" Width="30" Click="Button_Click"/>
                </StackPanel>
            </Border>
        </Viewbox>

    </Grid>
</UserControl>

后面的代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace DependencyPropertiesTest
{
    /// <summary>
    /// Interaction logic for UserControl1.xaml
    /// </summary>
    public partial class UserControl1 : UserControl, INotifyPropertyChanged
    {
        public UserControl1()
        {
            InitializeComponent();
            DataContext = this;
        }



        public int UserControlNumber
        {
            get { return (int)GetValue(UserControlNumberProperty); }
            set { SetValue(UserControlNumberProperty, value); }
        }

        // Using a DependencyProperty as the backing store for UserControlNumber.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty UserControlNumberProperty =
            DependencyProperty.Register("UserControlNumber", typeof(int), typeof(UserControl1), new PropertyMetadata(0));



        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            UserControlNumber++;
        }
    }
}

主窗口中的两个按钮应分别增加用户控件文本块中的值,一个来自窗口,一个来自控件本身。我可以将主窗口中的值设置为这样的文字:

<local:UserControl1 Margin="10" UserControlNumber="5"/>

但是当我尝试给它一个绑定值时,它不起作用。使用 Snoop 检查绑定会出现以下错误:

消息:无法设置表达式。它被标记为“NonShareable”并且已被使用。

更新。

我现在已经试过了,但还是不行:

        public int UserControlNumber
    {
        get { return (int)GetValue(UserControlNumberProperty); }
        set { SetValue(UserControlNumberProperty, value); }
    }

    // Using a DependencyProperty as the backing store for UserControlNumber.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty UserControlNumberProperty =
        DependencyProperty.Register("UserControlNumber", typeof(int), typeof(UserControl1), new PropertyMetadata(0, TextBlockPropertyChanged));

    private static void TextBlockPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        UserControl1 uc1 = d as UserControl1;
        int newNumber = (int)e.NewValue;

        uc1.MyTextBlock.Text = newNumber.ToString();
    }

在主窗口中:

<local:UserControl1 Margin="10" UserControlNumber="{Binding Number, Mode=TwoWay}"/>

【问题讨论】:

  • 我总是在元数据中设置属性更改回调,并使用它来设置回调中的文本块。它从客户端应用程序绑定。你考虑过这种方法吗?
  • 我试了一下。看到更新,你是这个意思吗?

标签: c# wpf user-controls dependency-properties


【解决方案1】:

在您的 Window Xaml 中,您可以在 TwoWays 模式下绑定:

<local:UserControl1 Margin="10" UserControlNumber="{Binding Number, Mode=TwoWays}"/>

否则在 User 控件内部,该值会增加,但窗口中的绑定不会让它改变......使用 TwoWays 绑定时,窗口中的 Number 也会改变。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-13
    相关资源
    最近更新 更多