WPF自定义控件的数据绑定不起作用

时间:2019-01-12 07:48:08

标签: c# .net wpf xaml

您好,感谢您的关注。 (我很抱歉对问题进行了太多编辑,却忘了先进行适当的校对)

我当前正在尝试开发一个新的WPF自定义控件,该控件在文本字段内包含一个小的加号按钮,用于添加新项目,以替换UI中的单独按钮和文本框。听起来很简单,但是无论我尝试多少,我似乎都无法正确理解数据绑定。

该应用程序应该可以与用户一起在我的用户控件的文本框中输入名称,然后当在我的自定义控件中绑定到添加命令的按钮被按下然后附加到AddCommand句柄的方法时,用户控件的按钮将触发AddCommand其余的。

通常我不会收到错误,问题是由于应用程序其他部分中的某些代码,如果我绑定到字段的“文本框”(例如:NewPsCondition.Name)为空(或在这种情况下,未正确绑定)应用程序不允许我实际触发AddCommand(通过“正确地”绑定到AddCommand的按钮激活)。但是,当我尝试从自己的自定义控件的按钮触发AddCommand时,如果尝试在自己控件的文本框中设置NewPsCondition.Name并在另一个按钮上触发AddCommand,则始终会出现错误,该按钮将处于非活动状态。进一步表明我没有行使约束力。

到目前为止,我尝试了在Stackoverflow和google上找到的所有其他答案,例如:

  • this.DataContext = this;添加到自定义用户控件构造函数中。
  • RootElement.DataContext = this添加到自定义用户控件构造函数中。
  • 确保在我称为用户控件的地方设置“ Mode = TwoWay”。
  • 通过按原样测试所有内容,但像以前一样使用单独的按钮和文本框,确保问题确实出在自定义用户控件上。

这是我应该调用控件的地方之一以及现在如何调用它的示例:

<StackPanel Orientation="Horizontal" >
                    <Label Content="نام"></Label>
<!--These bindings don't work-->
                    <control:AddFieldMV Margin="35px 0" Width="132px" SubmitCommand="{Binding Path=AddCommand}" InputText="{Binding Path=NewPsCondition.Name,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
<!--These bindings do-->                    
                    <Button  Content="اضافه" Command="{Binding Path=AddCommand}" Click="ButtonBase_OnClick"></Button>
                    <TextBox Text="{Binding Path=NewPsCondition.Name,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" Width="60px" Margin="40px 0"></TextBox>
</StackPanel>

这是我的自定义控件的xaml代码:

<UserControl x:Class="TestInstrumentApplication.ResourceDictionary.Control.AddFieldMV"
             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:local="clr-namespace:TestInstrumentApplication.ResourceDictionary.Control"
             mc:Ignorable="d" 
             DataContext="this"
             MinHeight="20px" MinWidth="70px">
    <Grid x:Name="RootElement">
        <Border
            BorderBrush="#6D6E71"
            BorderThickness="0 0 0 1"
            CornerRadius="0">
            <Grid MinHeight="20" Background="#F1F2F2">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*"></ColumnDefinition>
                    <ColumnDefinition  Width="15"></ColumnDefinition>
                </Grid.ColumnDefinitions>
                <TextBox MinWidth="50" Grid.Column="0" HorizontalContentAlignment="Center" VerticalAlignment="Center" VerticalContentAlignment="Center" BorderThickness="0" Background="Transparent" Text="{Binding Path=InputText}">
                </TextBox>
                <Button Grid.Column="1" Height="20px" BorderBrush="Transparent" Click="AddButton_OnClick">
                    <Button.Background>
                        <VisualBrush  >
                            <VisualBrush.Visual>
                                <Canvas Width="14.250" Height="14.250">
                                    <!--there were some working vector graphics here that I removed to keep it short-->                                </Canvas>
                            </VisualBrush.Visual>
                        </VisualBrush>
                    </Button.Background>
                </Button>
            </Grid>
        </Border>
    </Grid>
</UserControl>

最后,这些是xaml代码后面的自定义控件的C#代码

using System;
using System.Collections.Generic;
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;
using TestInstrumentApplication.Utility;

namespace TestInstrumentApplication.ResourceDictionary.Control
{
    /// <summary>
    /// Interaction logic for AddFieldMV.xaml
    /// </summary>
    public partial class AddFieldMV : UserControl
    {
        public AddFieldMV()
        {
            InitializeComponent();
            RootElement.DataContext = this;
        }

        public event EventHandler AddButtonClicked;

        protected virtual void OnAddButtonClicked(EventArgs e)
        {
            AddButtonClicked?.Invoke(this, e);
        }

        private void AddButton_OnClick(object sender, RoutedEventArgs e)
        {
            OnAddButtonClicked(e);
            //here I get a bug when I hit button on running application telling me SubmitCommand is null
            SubmitCommand.Execute(sender);
        }

        public static readonly DependencyProperty SubmitCommandProperty
            = DependencyProperty.Register(
                "SubmitCommand",
                typeof(ICommand),
                typeof(AddFieldMV));

        public ICommand SubmitCommand
        {
            get => (ICommand)GetValue(SubmitCommandProperty);
            set => SetValue(SubmitCommandProperty, value);
        }

        public static readonly DependencyProperty InputTextProperty
            = DependencyProperty.Register(
                "InputText",
                typeof(string),
                typeof(AddFieldMV),
                new PropertyMetadata(default(string)));

        public string InputText
        {
            get
            {
                return (string)GetValue(InputTextProperty);
            }
            set { SetValue(InputTextProperty, value); }
        }

        private static void CustomTextBox_OnTextPropertyChanged(DependencyObject d,
            DependencyPropertyChangedEventArgs e)
        {
            AddFieldMV customTextBox = d as AddFieldMV;

            customTextBox.SetValue(InputTextProperty, e.NewValue);
        }
    }
}

0 个答案:

没有答案