使用DataTriggers WPF持续动态添加控件

时间:2015-05-12 04:00:49

标签: c# wpf xaml persistence caliburn.micro

我目前正在开发一个使用Caliburn.Micro的WPF项目,但我希望你可以提供帮助。我有一个表单,允许用户将新字段添加到单独的表单,意图这些新字段将保持不变。我可以使用以下代码动态创建这些控件:

        Grid tmpOuterGrid = new Grid();
        RowDefinition rowDefinition1 = new RowDefinition();
        RowDefinition rowDefinition2 = new RowDefinition();
        rowDefinition1.Height = new GridLength(45, GridUnitType.Star);
        rowDefinition2.Height = new GridLength(55, GridUnitType.Star);
        tmpOuterGrid.RowDefinitions.Add(rowDefinition1);
        tmpOuterGrid.RowDefinitions.Add(rowDefinition2);
        tmpOuterGrid.Margin = new Thickness(0,0,0,10);

        Grid tmpInnerGrid = new Grid();
        Grid.SetRow(tmpInnerGrid, 0);
        tmpInnerGrid.Margin = new Thickness(10,0,0,5);
        tmpInnerGrid.Opacity = 0;

        DataTrigger d = new DataTrigger();
        Binding b = new Binding("DisplayFieldName");
        b.Source = _fieldNames[primaryNameBase + "FieldTextBox"];
        d.Binding = b;
        d.Value = true;

        Storyboard sbEnter = new Storyboard();
        DoubleAnimation opAnimShow = new DoubleAnimation(1,new Duration(new TimeSpan(0,0,0,1)));
        Storyboard.SetTargetProperty(sbEnter, new PropertyPath(UIElement.OpacityProperty));
        sbEnter.Children.Add(opAnimShow);

        Storyboard sbExit = new Storyboard();
        DoubleAnimation opAnimHide = new DoubleAnimation(0, new Duration(new TimeSpan(0, 0, 0, 1)));
        Storyboard.SetTargetProperty(sbExit, new PropertyPath(UIElement.OpacityProperty));
        sbExit.Children.Add(opAnimHide);

        BeginStoryboard bsEnter = new BeginStoryboard { Storyboard = sbEnter, Name = "beginStoryboardEnter" };
        BeginStoryboard bsExit = new BeginStoryboard { Storyboard = sbExit, Name = "beginStoryboardExit" };

        d.EnterActions.Add(bsEnter);
        d.ExitActions.Add(bsExit);

        Style st = new Style(typeof(Grid));
        st.Triggers.Add(d);
        tmpInnerGrid.Style = st;

        TextBlock tb = new TextBlock();
        tb.Name = primaryNameBase + "FieldHeaderText";
        tb.Foreground = new SolidColorBrush(Color.FromArgb(136,255,255,255));
        tb.FontSize = 14;
        tb.Style = (Style) App.Current.Resources["NexaLightTextBlock"];
        tb.HorizontalAlignment = HorizontalAlignment.Center;
        tb.Text = fieldTextBox.DisplayText;

        Border underline = new Border();
        underline.BorderThickness = new Thickness(0, 0, 0, 1);
        underline.BorderBrush = new SolidColorBrush(Color.FromArgb(136,49,250,250));
        underline.VerticalAlignment = VerticalAlignment.Bottom;
        underline.HorizontalAlignment = HorizontalAlignment.Center;

        Binding binding = new Binding
        {
            Source = tb,
            Path = new PropertyPath("ActualWidth"),
        };
        underline.SetBinding(FrameworkElement.WidthProperty, binding);

        tmpInnerGrid.Children.Add(tb);
        tmpInnerGrid.Children.Add(underline);

        LowBorderTextBox lbtb = new LowBorderTextBox();
        lbtb.Name = primaryNameBase + "FieldTextBox";
        Grid.SetRow(lbtb, 1);
        lbtb.Width = 140;
        lbtb.Margin = new Thickness(10,0,0,0);
        lbtb.FontColor = new SolidColorBrush(Colors.White);
        lbtb.DisplayFontSize = 22;
        lbtb.Style = (Style) App.Current.Resources["NexaLightCustomTextBox"];
        lbtb.DisplayText = fieldTextBox.DisplayText;
        lbtb.LostFocus += FieldLostFocus;

        tmpOuterGrid.Children.Add(tmpInnerGrid);
        tmpOuterGrid.Children.Add(lbtb);

        wrapPanel.Children.Add(tmpOuterGrid);

然后,我希望通过应用程序关闭来保留这些新控件。我想要采用的方法是将对象序列化为xaml并将其存储在文件中,然后读取该文件并对其进行反序列化以再次获取控制对象,这将添加到我周围的WrapPanel中。除了一个细节,这一切都很好,花花公子。创建的控件具有带有datatrigger的样式,该样式绑定到NoteField对象的属性,每种控件都有一个NoteField对象。我还计划序列化NoteField对象,这样我就可以将它们拉回来并希望绑定仍然完好,但是它们实现了Caliburn.Micro框架的PropertyChangedBase接口,并且NotifyOfPropertyChange()方法不是标记为可序列化。这是NoteField类:

[Serializable]
class NoteField : PropertyChangedBase
{
    private string _controlName;

    private bool _displayFieldName;

    public bool DisplayFieldName
    {
        get { return _displayFieldName; }
        set
        {
            _displayFieldName = value;
            NotifyOfPropertyChange(() => DisplayFieldName);
        }
    }

    private string _fieldName;

    public string FieldName
    {
        get { return _fieldName; }
        set
        {
            _fieldName = value;
            NotifyOfPropertyChange(() => FieldName);
        }
    }

    public NoteField(string controlName, string displayText)
    {
        DisplayFieldName = false;
        _controlName = controlName;
        FieldName = displayText;
    }

    public string GetControlName()
    {
        return _controlName;
    }

    public void SetControlName(string name)
    {
        _controlName = name;
    }
}

我不喜欢使用这个类,但这是我能想到动态生成属性从xaml绑定的唯一方法。所以,我想我的问题是:是否有一种方法可以动态创建具有绑定的控件,这些绑定可以通过应用程序关闭持续存在?我是在正确的轨道上,还是我应该一起做其他事情?任何帮助将不胜感激。非常感谢你的时间。

0 个答案:

没有答案
相关问题