WPF - 无法通过反序列化设置动态添加的用户控件的属性

时间:2014-03-18 10:49:31

标签: c# wpf


文件des.txt - >此文件被反序列化为xaml tree

<NewLabel NewText="some new text" LabelText="yes" xmlns="clr-namespace:WpfPractice;assembly=WpfPractice" xmlns:av="http://schemas.microsoft.com/winfx/2006/xaml/presentation"><av:Grid><av:Canvas><av:TextBox Width="100" Height="30">yes</av:TextBox></av:Canvas></av:Grid></NewLabel>

Mainwindow.xaml

<Window x:Class="WpfPractice.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfPractice"
    Title="MainWindow"
    Width="525"
    Height="350">
<Grid Name="theGrid">
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
    </Grid.RowDefinitions>
    <Button Grid.Row="1"
            Width="50"
            Height="25"
            Click="Button_Click_2"
            Content="Click" />
</Grid>

MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.IO;
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.Markup;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Xml;

namespace WpfPractice
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    NewLabel someNewLabel;
    public MainWindow()
    {
        InitializeComponent();

        someNewLabel = (NewLabel)DeserializeXaml(File.ReadAllText(@"D:\des.txt"));

        theGrid.Children.Add(someNewLabel);
    }

    void Serialize()
    {
        NewLabel theNewLabel = new NewLabel();

        theNewLabel.NewText = "some new text";

        string xamlString = XamlWriter.Save(theNewLabel);

        XmlReader reader = XmlReader.Create(new StringReader(xamlString));

        UIElement copy = XamlReader.Load(reader) as UIElement;
    }

    private void Button_Click_2(object sender, RoutedEventArgs e)
    {
        someNewLabel.LabelText = "new value";

        someNewLabel.SetLabelValue("asdfsadgsafgreg");

        //Serialize();
    }


    public object DeserializeXaml(string xaml)
    {
        StringReader stringReader = new StringReader(xaml);

        XmlReader xmlReader = XmlReader.Create(stringReader);

        return System.Windows.Markup.XamlReader.Load(xmlReader);
    }
    }

}

NewLabel.xaml

<UserControl x:Class="WpfPractice.NewLabel"
         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"
         d:DesignHeight="300"
         d:DesignWidth="300"
         mc:Ignorable="d">
    <Grid Name="theGrid">


    </Grid>

NewLabel.xaml.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
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 WpfPractice
{
/// <summary>
/// Interaction logic for NewLabel.xaml
/// </summary>
public partial class NewLabel : UserControl, INotifyPropertyChanged
{

    public static DependencyProperty NameProperty =
   DependencyProperty.Register("NewText",
                               typeof(string),
                               typeof(NewLabel),
                               new PropertyMetadata(String.Empty));

    public string NewText
    {
        get { return (string)GetValue(NameProperty); }
        set { SetValue(NameProperty, value); }
    }


    private string _labelText = "yes";
    public string LabelText
    {
        get
        {
            return _labelText;
        }
        set
        {
            _labelText = value;
            OnPropertyChanged("LabelText");
        }
    }

    Label theLabel;
    public NewLabel()
    {
        InitializeComponent();

        theLabel = new Label();

        theLabel.Height = 30;

        theLabel.Width = 100;

        theLabel.Content = "old value";

        Canvas theCanvas = new Canvas();

        theCanvas.Children.Add(theLabel);

        theGrid.Children.Add(theCanvas);

        Binding b = new Binding("LabelText");

        b.Source = this;

        theLabel.SetBinding(TextBox.TextProperty, b);

        theLabel.MouseDoubleClick += theLabel_MouseDoubleClick;

        this.DataContext = this;
    }

    void theLabel_MouseDoubleClick(object sender, MouseButtonEventArgs e)
    {
        MessageBox.Show("clicked!");
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    }


    public void SetLabelValue(string val)
    {
        theLabel.Content = val;
    }
}

}

问题:

MainWindow.xaml.cs中的这两个语句

      someNewLabel.LabelText = "new value";

        someNewLabel.SetLabelValue("asdfsadgsafgreg");

不行。换句话说,我无法将textbox属性设置为“new value”

1 个答案:

答案 0 :(得分:2)

您正在NewLable构造函数中创建绑定,但随后从文件中加载新的可视树,该文件将覆盖原始文件。这就是为什么你不能更新标签,也不能通过直接设置值来绑定,因为它不再在可视树中了。