WPF多文本框用户控件

时间:2013-01-08 19:00:41

标签: wpf user-controls

我希望有一个用户控件[说UC1]包含4个文本框[比如说tb1,tb2,tb3和tb4]。此用户控件应具有4个正常属性[比如prop1,prop2,prop3和prop4]绑定到这些文本框。我想要一个依赖属性[说dp]通过这个用户控件暴露给外部世界。 这个用户控件从类[说StrProp]类[比如说C1]得到一个字符串[比如0 \ abc | 1 \ def | 2 \ ghi | 3 \ jkl]并分成4个部分[比如abc,def, ghi和jkl]显示在我的用户控件的4个文本框中。如果用户在任何或所有文本框中进行了任何更改,则应将所有已更改的文本组合并反映回C1 \ StrProp类属性。 另外,我的要求是dp应该绑定到UI \ XAML中的StrProp。验证也应该正确完成。

任何人都可以通过编写一个例子来帮助我吗? 示例类如下:

MyMultiTextBoxUserControl.xaml

<UserControl x:Class="MyMultiTextBoxControl_UsingNConsuming.MyMultiTextBoxUserControl"
             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">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height=".25*"/>
            <RowDefinition Height=".25*"/>
            <RowDefinition Height=".25*"/>
            <RowDefinition Height=".25*"/>
        </Grid.RowDefinitions>
        <TextBox Grid.Row="0" Text="{Binding ElementName=UserControl, Path=CombinedField1 }"/>
        <TextBox Grid.Row="1" Text="{Binding ElementName=UserControl, Path=CombinedField2}"/>
        <TextBox Grid.Row="2" Text="{Binding ElementName=UserControl, Path=CombinedField3}"/>
        <TextBox Grid.Row="3" Text="{Binding ElementName=UserControl, Path=CombinedField4}"/>
    </Grid>
</UserControl>

MyMultiTextBoxUserControl.xaml.cs

public partial class MyMultiTextBoxUserControl : UserControl
    {
        public MyMultiTextBoxUserControl()
        {
            InitializeComponent();
        }

        //static FrameworkPropertyMetadata propertydata = new FrameworkPropertyMetadata("Hello",
        //    FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback(PropertyChanged_Callback), new CoerceValueCallback(CoerceValue_Callback),
        //    false, UpdateSourceTrigger.LostFocus);

        //public static readonly DependencyProperty CombinedTextProperty =
        //    DependencyProperty.Register("CombinedText", typeof(string), typeof(MyMultiTextBoxUserControl), propertydata, new ValidateValueCallback(Validate_ValueCallback));


        static FrameworkPropertyMetadata propertydata = new FrameworkPropertyMetadata("Hello",
           FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback(PropertyChanged_Callback));
        public static readonly DependencyProperty CombinedTextProperty =
            DependencyProperty.Register("CombinedText", typeof(string), typeof(MyMultiTextBoxUserControl), propertydata);


        private static bool Validate_ValueCallback(object value)
        {
            string str=value as string;
            bool result = true;
            if (str.Length > 28)
                result = false;
            if (str.Length < 1)
                result = false;
            if (str.Substring(0, 2) != "0'\'")
                result = false;
            if (str.Contains("1'\'") == false || str.Contains("2'\'") || str.Contains("3'\'"))
                result = false;
            return result;
        }

        private static object CoerceValue_Callback(DependencyObject obj,object value)
        {
            return value;
        }

        private static void PropertyChanged_Callback(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {            
            MyMultiTextBoxUserControl control=(MyMultiTextBoxUserControl)obj;
            string select = e.NewValue.ToString();
            char[] pipeDelim,slashDelim;
            string[] pipeSplt;
            pipeDelim = new char[] { '|' };
            slashDelim = new Char[] { '/' };
            pipeSplt = select.Split(pipeDelim);
            if (pipeSplt.Length == 1)
                return;
            string[][] str = new string[4][];
            int x = 0;
            foreach (string s in pipeSplt)
            {
                if (string.IsNullOrEmpty(s) == false)
                {
                    str[x] = s.Split(slashDelim);
                    x++;
                }
            }
            control.CombinedField1 = str[0][1];
            control.CombinedField2 = str[1][1];
            control.CombinedField3 = str[2][1];
            control.CombinedField4 = str[3][1];
        }

        public string CombinedText
        {
            get { return GetValue(CombinedTextProperty) as string; }
            set { SetValue(CombinedTextProperty, value); }
        }

        public string CombinedField1 
        {
            get;  set; 
        }

        public string CombinedField2
        {
            get;
            set;
        }

        public string CombinedField3
        {
            get;
            set;
        }

        public string CombinedField4
        {
            get;
            set;
        }
    }

CombinedStringClass.cs

namespace MyMultiTextBoxControl_UsingNConsuming
{
    public class CombinedStringClass
    {
        public CombinedStringClass() { }
        string m_CombinedString;
        public string CombinedString
        {
            get { return m_CombinedString; }
            set
            {
                if (m_CombinedString != value)
                    m_CombinedString = value;
            }
        }
    }
}

ConsumerClass.xaml

<Window x:Class="MyMultiTextBoxControl_UsingNConsuming.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:MyMultiTextBoxControl_UsingNConsuming;assembly="        
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <local:CombinedStringClass x:Key="myClass"/>
    </Window.Resources>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="0.5*"/>
            <ColumnDefinition Width="0.5*"/>
        </Grid.ColumnDefinitions>        
        <Grid.RowDefinitions>
            <RowDefinition Height="0.33*"/>
            <RowDefinition Height="0.34*"/>
            <RowDefinition Height="0.33*"/>
        </Grid.RowDefinitions>
        <TextBlock Text="User Control Text Boxes" Grid.Row="0" Grid.Column="0" Foreground="Black" VerticalAlignment="Center" HorizontalAlignment="Center"/>
        <local:MyMultiTextBoxUserControl Grid.Row="0" Grid.Column="1" Foreground="Black" CombinedText="{Binding Source=myClass, Path=CombinedString, Mode=TwoWay,FallbackValue=DataNotBound}"/>
        <TextBlock Text="Combied String" Grid.Row="2" Grid.Column="0" Foreground="Black" VerticalAlignment="Center" HorizontalAlignment="Center"/>
        <TextBox Name="OneStringTextBox" Grid.Row="2" Grid.Column="1" Foreground="Black" Text="0\abc|1\def|2\ghi|3\jkl" IsEnabled="False"/>
    </Grid>
</Window>

我还需要将更改后的文本管理器组合在一起,以便它应该以[0 \ f | 1 \ gh | 2 \ zx | 3 \ oo]的形式反映在OneStringTextBox中。此外,总串长度应为28&amp;每个文本框的最大长度为7。

1 个答案:

答案 0 :(得分:0)

阅读WPF in C# 2010: Windows Presentation Foundation in .NET 4 Matthew MacDonald第18章。 有一个很好的例子可以帮助你。

为您的用户控件命名,将{Binding ElementName = UserControl ...替换为{Binding ElementName = NameOfUserControl,将CombinedFields属性转换为DP。