c#如何使用“实现INotifyPropertyChanged”或“继承DependencyObject”

时间:2019-10-06 10:10:07

标签: c# wpf xaml

我是C#,XAML和OO编程的初学者。因此,我想创建一个UI示例以了解其工作方式。在XAML中创建UI以及在Windows.Resourses内部创建对象的许多部分非常重要。

我开始尝试这个问题: Object created in XAML can't be called by x:Name in cs,因为我无法调用在Windows.Resourses内部创建的对象。这个问题已得到完全回答,但正如前面提到的,对象只能在初始化期间进行操作。

否则,我应该更改某些属性,应该使用实现INotifyPropertyChanged 继承DependencyObject

如下图所示,标签的内容在初始化期间填充,但是如果我想通过单击按钮更改内容,my_WidgetItem函数中无法识别onClick( )

我对实现INotifyPropertyChanged 继承DependencyObject 的使用感到非常困惑。 有人可以根据下面的代码为我提供帮助吗?

这是MainWindow.xaml.cs文件:

<Window x:Class="test2.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:test2"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800">

<Window.Resources>
    <DataTemplate x:Key="something">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <Label x:Name="myLabel1" Grid.Row="0" Content="{Binding Title1}"/>
            <Label x:Name="myLabel11" Grid.Row="1" Content="{Binding Title2}"/>
        </Grid>
    </DataTemplate>
</Window.Resources>

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="*"/>
        <RowDefinition Height="*"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <ContentPresenter x:Name="myContentPresenter" Grid.Row="0" ContentTemplate="{StaticResource something}" />
    <Label x:Name="myLabel2" Content="Labe2" Grid.Row="1" />
    <Label x:Name="myLabel3" Content="Labe3" Grid.Row="2" />
    <Button Margin="4" Content="click me" Grid.Row="3" Click="onClick"/>
</Grid>

这是MainWindow.cs文件:

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;

namespace test2
{
    public partial class MainWindow : Window
    {
        public class Widget
        {
            public string Title1 { get; set; }
            public string Title2 { get; set; }
        }
        public MainWindow()
        {
            InitializeComponent();
            myLabel2.Content = "new content myLabel2";
            myLabel3.Content = "new content myLabel3";

            Widget my_widgetItem = new Widget();
            my_widgetItem.Title1 = "new content while initialization a";
            my_widgetItem.Title2 = "new content while initialization b";

            myContentPresenter.Content = my_widgetItem;
        }

        private void onClick(object sender, RoutedEventArgs e)
        {
            /// Now, I want to change the Label's content.
            myLabel2.Content = "label changed"; /// O.K.
            my_widgetItem.Title2 = "new content after click";
            /// my_widgetItem does not exist in the current content.
        }
    }

2 个答案:

答案 0 :(得分:1)

A cookie associated with a cross-site resource at https://docs.google.com/ was set without the `SameSite` attribute. A future release of Chrome will only deliver cookies with cross-site requests if they are set with `SameSite=None` and `Secure`. You can review cookies in developer tools under Application>Storage>Cookies and see more details at https://www.chromestatus.com/feature/5088147346030592 and https://www.chromestatus.com/feature/5633521622188032. 是一个局部变量,在MainWindow构造函数中声明。不能在构造函数之外使用。

您可以通过my_widgetItem方法取回它:

onClick

答案 1 :(得分:1)

如果存储对在构造函数中创建的Widget的引用,则可以在事件处理程序中直接访问它:

private Widget my_widgetItem;

public MainWindow()
{
    InitializeComponent();
    myLabel2.Content = "new content myLabel2";
    myLabel3.Content = "new content myLabel3";

    my_widgetItem = new Widget();
    my_widgetItem.Title1 = "new content while initialization a";
    my_widgetItem.Title2 = "new content while initialization b";

    myContentPresenter.Content = my_widgetItem;
}

private void onClick(object sender, RoutedEventArgs e)
{
    myLabel2.Content = "label changed"; /// O.K.
    my_widgetItem.Title2 = "new content after click";
}

但是对于绑定到Label的{​​{1}}中的ContentTemplateTitle2类还必须实现INotifyPropertyChanged并引发更改通知事件:

Widget