单击按钮时无法获得价值

时间:2019-07-24 16:06:30

标签: c# wpf data-binding

单击按钮时,使用数据绑定从另一个UserControl获取值

所以,我有一个嵌套在另一个也位于主窗口中的UserControl中的UserControl,

MainWindow.xaml:

<Window
    xmlns:view="clr-namespace:InvoiceAppV2.View"

    <Grid>
        <TabControl>
            <TabItem>
                <view:InvoiceControl>
            </TabItem>
            <TabItem/>
            <TabItem/>
        </TabControl>
    </Grid>
</Window>

MainWindow.xaml.cs:

public partial class MainWindow : Window
{

    public MainWindow()
    {
        InitializeComponent();
    }
}

InvoiceControl xaml:

<UserControl
    xmlns:view="clr-namespace:InvoiceAppV2.View"
    <Grid>
        <view:BuyerInfoControl/>
    </Grid>

    <Button x:Name="btnSubmit" Content="Submit" Click="BtnSubmit_Click"/>
</UserControl>

InvoiceControl.xaml.cs

public partial class InvoiceControl : UserControl
{
    Buyer b = new Buyer();

    public InvoiceUserControl()
    {
        InitializeComponent();
    }

    private void BtnSubmit_Click(object sender, RoutedEventArgs e)
    {
        MessageBox.Show(b.BuyerName);
    }
}

BuyerInfoControl xaml:

<UserControl
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>

    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition/>
    </Grid.RowDefinitions>
    <Label Content="Buyer's Name"/>
    <Label Content="Purchase Date"/>
    <TextBox x:Name="txtBuyerName" Text="{Binding Path=BuyerName, Mode=TwoWay}" 
                                       TextWrapping="NoWrap"/>
    <DatePicker x:Name="txtPurchaseDate" Text="{Binding Path=PurchaseDate, Mode=TwoWay}" />
</Grid>

这是处理属性更改的代码

 public class Buyer: INotifyPropertyChanged
{
    private int _id;
    private string _name;

    public event PropertyChangedEventHandler PropertyChanged = delegate { };   

    public int ID
    {
        get { return _id; }
        set { _id = value; }
    }

    public string BuyerName
    {
        get { return _name; }
        set
        {
            if(_name != value)
            {
                _name = value;
                PropertyChanged(this, new PropertyChangedEventArgs("BuyerName"));
            }
        }
    }

    public Buyer() {}

    public Buyer(int id, string name)
    {
        ID = id;
        BuyerName = name;
    }

    public Buyer(string name)
    {
        ID = 0;
        BuyerName = name;
    }
}

xaml.cs

 public partial class BuyerInfoControl : UserControl
{
    Buyer b;
    public BuyerInfoControl()
    {
        InitializeComponent();

        b = new Buyer(txtBuyerName.Text);
        this.DataContext = b;
    }
}

在文本框中键入“ John Doe”的值并单击该按钮时,买方的名称为null。我通常在swfit,object-c和MVC中工作。试图弄清楚如何使用MVVM和WPF。我觉得我在这里做错了。

这是设计

enter image description here

1 个答案:

答案 0 :(得分:0)

b = new Buyer(txtBuyerName.Text);仅获得对Text状态的最后引用;表示它是快照。

要实现正确的绑定,它必须在自定义控件所在的主页上进行,并且像TextBox一样,它将需要绑定到源字符串。为此,必须在自定义控件上提供Dependency Property

例如,如果将名为MyText的依赖项属性添加到控件绑定中,如下所示:

 <InvoiceControl MyText="{Binding Path=BuyerName}"/>
 <TextBox x:Name="txtBuyerName" Text="{Binding Path=BuyerName, Mode=TwoWay}" 
                                   TextWrapping="NoWrap"/>

由于InvoiceControl是用户控件,因此主页上的用户控件还必须绑定到原始BuyerName(如图所示)并执行您的操作希望它必须通过放在InvoiceControl上的依赖项属性来发生。

按如下所示连接InvoiceControl上的依赖项属性:

#region public string MyText
/// <summary>
/// This the dependency property for the control.
/// </summary>
public string MyText
{
    get { return GetValue(MyTextProperty) as string; }
    set { SetValue(MyTextProperty, value); }
}

/// <summary>
/// Identifies the MyText dependency property.
/// </summary>
public static readonly DependencyProperty MyTextProperty =
    DependencyProperty.Register(
        "MyText",
        typeof(string),
        typeof(InvoiceControl),
        new PropertyMetadata(string.Empty));
#endregion public string MyText

然后像这样加载

MessageBox.Show(MyText);

请参见Dependancy Property Overview


在键入控件后,您尝试单击按钮也可能会出现问题,并且不会触发正确的change事件。

TextBox上的绑定UpdateSourceTrigger=PropertyChanged中,以便每个文本更改都会发送一条通知消息。这样,如果一个人输入并且将焦点移到该按钮上,则会触发两种方式的绑定通知。


请注意,如果您使用自定义控件,则此链接具有Visual Studio代码段,这些代码段在可填充模板中用于编辑器中的依赖项属性。忽略Siverlight,代码段适用于所有版本的Visual Studio:

Helpful Silverlight Snippets - Jeff Wilcox