【问题标题】:How to assign property (get; set;) to a WPF User Control?如何将属性(获取;设置;)分配给 WPF 用户控件?
【发布时间】:2017-04-14 06:41:05
【问题描述】:

我正在尝试学习 C# 中的属性(获取和设置)。正如您在图片中看到的那样,我还是该语言的新手,目前正在使用带有一些文本框的 WPF 制作一个简单的程序。

所以,这里是描述:

  • Input : 这是用户可以输入输入的地方,位于 MainWindow
  • 输出 1:在输入中查看输入字符串的位置,位于 MainWindow
  • 输出 2:与输出 1 相同,位于第一个选项卡内,位于 MainWindow。
  • 输出 3:与输出 1 相同,位于选项卡 2 内,仍位于 MainWindow。
  • 输出 4:与输出 1 相同,位于选项卡 2 内,引用本地 UserControl Page1。
  • 按钮:“保存”输入的按钮

以下是代码: 主窗口:解决方案 --> 我在local:page1 之后添加了x:Name="Page1"

<!-- MainWindow.xaml -->
<Window x:Class="TestGetSet.MainWindow"
    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"
    xmlns:local="clr-namespace:TestGetSet"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <TabControl x:Name="tabControl" HorizontalAlignment="Left" Height="212" Margin="37,20,0,0" VerticalAlignment="Top" Width="447">
        <TabItem Header="TabItem">
            <Grid Background="#FFE5E5E5">
                <TextBox x:Name="output2" HorizontalAlignment="Left" Height="23" Margin="156,76,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="120"/>
                <Label x:Name="label2" Content="Output 2" HorizontalAlignment="Left" Margin="156,46,0,0" VerticalAlignment="Top"/>
            </Grid>
        </TabItem>

        <TabItem Header="TabItem">
            <Grid Background="#FFE5E5E5">
                <TextBox x:Name="output3" HorizontalAlignment="Left" Height="23" Margin="321,26,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/>
                <local:Page1 x:Name="Page1"/>
                <Label x:Name="label3" Content="Output 3" HorizontalAlignment="Left" Margin="321,0,0,0" VerticalAlignment="Top"/>
            </Grid>
        </TabItem>
    </TabControl>

    <TextBox x:Name="input" Text=""/>
    <TextBox x:Name="output1" Text=""/>        
    <Button x:Name="button" Content="Button" Click="button_Click"/>
    <Label x:Name="label" Content="Input" HorizontalAlignment="Left" Margin="37,239,0,0" VerticalAlignment="Top"/>
    <Label x:Name="label1" Content="Output 1" HorizontalAlignment="Left" Margin="364,239,0,0" VerticalAlignment="Top"/>

</Grid>

MainWindow 后面代码:解决办法 --> 加了一行Page1.passingvalue(..)

// MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;

public partial class MainWindow : Window
{
    public myProperty myProp = new myProperty();

    public MainWindow()
    {
        InitializeComponent();
    }

    private void button_Click(object sender, RoutedEventArgs e)
    {     
        myProp.myData = input.Text;
        output1.Text = myProp.myData;
        output2.Text = myProp.myData;
        output3.Text = myProp.myData;

        Page1.passingvalue(myProp.myData);
    }
}

接下来是 Page1.xaml(这里没有对解决方案进行任何更改)

<!-- Page1.xaml-->
<UserControl x:Class="TestGetSet.Page1"
  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:TestGetSet"
  mc:Ignorable="d" 
  d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <TextBox x:Name="output4" Text=""/>
        <Label x:Name="label" Content="Output 4" HorizontalAlignment="Left" Margin="92,110,0,0" VerticalAlignment="Top"/>
    </Grid>
</UserControl>

Page1 代码后面:解决方案--> 删除计时器并添加passingvalue

// Page1.xaml.cs    
using System;
using System.Windows.Controls;
using System.Windows.Threading;
using System.Threading;
using System.ComponentModel; 

namespace TestGetSet
{
    public partial class Page1 : UserControl
    {
        private Thread _receiveThread;
        myProperty myProp = new myProperty();

        public Page1()
        {
            InitializeComponent();

            /*DispatcherTimer MyTimer = new DispatcherTimer();
            MyTimer.Interval = new TimeSpan(0, 0, 0, 0, 100);  
            MyTimer.Tick += MyTimer_Tick;
            MyTimer.Start();*/
        }

        public void passingvalue(string m)
        {
            output4.Text = m;
        }

        /*private void MyTimer_Tick(object sender, EventArgs e)
        {
            output4.Text = myProp.myData;
        }*/
    }
}

最后一个,属性,简单版:

// myProperty.cs

namespace TestGetSet
{
    public class myProperty
    {
        public string myData { get; set }           
    }
}

带有 INotifyPropertyChanged 的​​属性:

// myProperty.cs
using System.ComponentModel;
namespace TestGetSet
{
    public class myProperty : INotifyPropertyChanged
    {
        private string _textdata;

        public string myData {
            get
            {
                return _textdata;
            }
            set
            {
                _textdata = value;
                NotifyPropertyChanged("myData");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}

以下是程序窗口的截图: onetwo

如您所见,只有 Output4 是空的,即使我不使用 INotifyPropertyChanged,其他输出仍然会给我结果。我的问题是为什么,我该如何解决这个问题?我想知道是不是因为我在 Page1 中使用了 UserControl,Output4 就在其中。我一直在寻找答案,但一无所获。任何帮助深表感谢。谢谢。

好的,所以我更新了代码。它现在正在工作。我从 How to Pass a Value From a Window to a UserControl in WPF 获得了 passingvalue 的参考资料

谢谢。

【问题讨论】:

  • 提供整个 XAML,使其看起来与您的图像完全一样。没有人会费心在你的代码中添加缺失的部分。
  • 在 page1 的代码隐藏中定义的属性 'myprop' 是类 'myProperty' 的新实例,因此它是空的。在 MainWindow 和 Page1 中定义的 myProperty 类型的属性是两个同名的属性,但是是同一个类的不同实例。如果你想在 mainwindow 和 page1 之间“共享”属性,你应该考虑使用数据绑定msdn.microsoft.com/en-us/library/ms752347(v=vs.110).aspx
  • @NareshRavlani 整个代码已添加。对不起。
  • 由于您没有使用绑定,因此您不必使用 INotifyPropertyChanged。尝试在 getter 中设置一些值,例如 public string myData { get {return "Bla";} set } 。现在你得到了 Bla
  • @MatijaK。当我尝试使用private string _textdata="bambi" public string myData{get{return _textdata;} set{_textdata value;}} ... output4 很好地显示了bambi。我不知道为什么。

标签: c# wpf inotifypropertychanged


【解决方案1】:

你的问题是你弄错了 MainWindow 的 myProperty 和 Page1 的 myProperty。

在 Page1 中,您使用 myProp.myData 设置了 output4.Text,这是错误的,因为 myProp 是 Page1 的 myProp,它永远不会更新。

如果您将 MainWindow 的引用传递给 Page1 并改为编写 output4.Text = myMainWindowReferenc.myProp.myData; 之类的内容,它将按预期工作。

您还可以通过在 XAML 中命名 Page1 来为 button_Click 函数中的 output4 添加设置:

private void button_Click(object sender, RoutedEventArgs e)
{
    myProp.myData = input.Text;
    output1.Text = myProp.myData;
    output2.Text = myProp.myData;
    output3.Text = myProp.myData;
    Page1.output4.Text = myProp.myData;
}

【讨论】:

  • 我现在明白了。所以我只需要在 MainWindow.xaml 中将x:Name="Page1" 放在local:Page1 旁边。非常感谢。我会用解决方案更新我的帖子。
猜你喜欢
  • 2014-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-27
  • 1970-01-01
相关资源
最近更新 更多