当从其控件内部调用而不是从主应用外部调用时,函数调用才起作用 [英] Function call works when called internally from in its control but not externally from the main app

查看:77
本文介绍了当从其控件内部调用而不是从主应用外部调用时,函数调用才起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用了从本网站检索到的一些代码来创建滚动终端类型窗口.该示例运行良好,因此我决定将其转换为基本控件,以便重新使用. 在控件中,我有一个"LogEntry"类型列表,该列表已数据绑定到"items控件",因此当列表更新时,items控件也将更新.可以通过调用"AddEntry"函数来更新此列表.当从控件内部调用此函数时,列表将通知"ItemsControl"已发生更新.当我从主窗口调用"AddEntry()"函数时,列表会更新,但"ItemsControl"不会得到更新通知. 谁能解释为什么? 谢谢你的帮助 问候 斯图尔特

I have used some code that i retrieved from this website to create a scrolling terminal type window. The example works very well, so i decided i would turn it into a basic control so i could reuse. In the control I have a "LogEntry" type list that is databound to an "items control" so when the list gets updated, so does the items control. This list gets updated by calling the "AddEntry" function. When this function is called internally from the control, the list notifies the "ItemsControl" that an update has occured. When I call the "AddEntry()" function from the main window, the list updates BUT the "ItemsControl" doesnt get the update notification. Can anyone explain why? Thanks for your help Regards Stuart

这是用户控件的代码

TerminalWindow.xaml.cs

TerminalWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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;
using System.Collections.ObjectModel;
using System.ComponentModel;

namespace ScrollingTerminalWindow
{
    /// <summary>
    /// example code retreived from this page
    /// http://stackoverflow.com/questions/16743804/implementing-a-log-viewer-with-wpf
    /// </summary>
    public partial class TerminalWindow : UserControl
    {
            private int index;
            private string TestData = "Lorem ipsum dolor sit amet, consectetur     adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum";
            private List<string> words;
            private int maxword;

            public ObservableCollection<LogEntry> LogEntries { get; set; }

            public TerminalWindow()
            {
                InitializeComponent();
                index = 0;
                DataContext= LogEntries = new ObservableCollection<LogEntry>();

                random = new Random();
                words = TestData.Split(' ').ToList();
                maxword = words.Count - 1;
                AddEntry();
                this.btnAddEntry.BringIntoView();
                this.btnAddEntry.Focus();

            }



             public void AddEntry()
            {
                Dispatcher.BeginInvoke((Action)(() =>     LogEntries.Add(GetRandomEntry())));
            }
             private System.Threading.Timer Timer;
             private System.Random random;
             private LogEntry GetRandomEntry()
             {
             if (random.Next(1, 10) > 1)
             {
                 return new LogEntry()
                 {
                     Index = index++,
                     DateTime = DateTime.Now,
                     Message = string.Join(" ", Enumerable.Range(5, random.Next(10, 50))
                                                          .Select(x => words[random.Next(0, maxword)])),
                 };
             }

             return new CollapsibleLogEntry()
             {
                 Index = index++,
                 DateTime = DateTime.Now,
                 Message = string.Join(" ", Enumerable.Range(5, random.Next(10, 50))
                                              .Select(x => words[random.Next(0, maxword)])),
                 Contents = Enumerable.Range(5, random.Next(5, 10))
                                      .Select(i => GetRandomEntry())
                                      .ToList()
             };

         }

         private void btnAddEntry_Click(object sender, RoutedEventArgs e)
         {
             AddEntry();
         }



    }
    public class LogEntry : PropertyChangedBase
    {
        public DateTime DateTime { get; set; }

        public int Index { get; set; }

        public string Message { get; set; }
    }

    public class CollapsibleLogEntry : LogEntry
    {
        public List<LogEntry> Contents { get; set; }
    }
    public class PropertyChangedBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            Application.Current.Dispatcher.BeginInvoke((Action)(() =>
            {
                PropertyChangedEventHandler handler = PropertyChanged;
                if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
            }));
        }
    }

}

TerminalWindow.XAML

TerminalWindow.XAML

<UserControl x:Class="ScrollingTerminalWindow.TerminalWindow"
         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:ScrollingTerminalWindow"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
    <Style TargetType="ItemsControl" x:Key="LogViewerStyle">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate>
                    <ScrollViewer CanContentScroll="True">
                        <ItemsPresenter/>
                    </ScrollViewer>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Setter Property="ItemsPanel">
            <Setter.Value>
                <ItemsPanelTemplate>
                    <VirtualizingStackPanel IsItemsHost="True"/>
                </ItemsPanelTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <DataTemplate DataType="{x:Type local:LogEntry}">
        <Grid IsSharedSizeScope="True">
            <Grid.ColumnDefinitions>
                <ColumnDefinition SharedSizeGroup="Index" Width="Auto"/>
                <ColumnDefinition SharedSizeGroup="Date" Width="Auto"/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <TextBlock Text="{Binding DateTime}" Grid.Column="0"
                   FontWeight="Bold" Margin="5,0,5,0"/>

            <TextBlock Text="{Binding Index}" Grid.Column="1"
                   FontWeight="Bold" Margin="0,0,2,0" />

            <TextBlock Text="{Binding Message}" Grid.Column="2"
                   TextWrapping="Wrap"/>
        </Grid>
    </DataTemplate>

    <DataTemplate DataType="{x:Type local:CollapsibleLogEntry}">
        <Grid IsSharedSizeScope="True">
            <Grid.ColumnDefinitions>
                <ColumnDefinition SharedSizeGroup="Index" Width="Auto"/>
                <ColumnDefinition SharedSizeGroup="Date" Width="Auto"/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>

            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition/>
            </Grid.RowDefinitions>

            <TextBlock Text="{Binding DateTime}" Grid.Column="0"
                   FontWeight="Bold" Margin="5,0,5,0"/>

            <TextBlock Text="{Binding Index}" Grid.Column="1"
                   FontWeight="Bold" Margin="0,0,2,0" />

            <TextBlock Text="{Binding Message}" Grid.Column="2"
                   TextWrapping="Wrap"/>

            <ToggleButton x:Name="Expander" Grid.Row="1" Grid.Column="0"
                      VerticalAlignment="Top" Content="+" HorizontalAlignment="Right"/>

            <ItemsControl ItemsSource="{Binding Contents}" Style="{StaticResource LogViewerStyle}"
                      Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2"
                      x:Name="Contents" Visibility="Collapsed"/>

        </Grid>
        <DataTemplate.Triggers>
            <Trigger SourceName="Expander" Property="IsChecked" Value="True">
                <Setter TargetName="Contents" Property="Visibility" Value="Visible"/>
                <Setter TargetName="Expander" Property="Content" Value="-"/>
            </Trigger>
        </DataTemplate.Triggers>
    </DataTemplate>

</UserControl.Resources>



<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="60"></RowDefinition>
        <RowDefinition Height="*"></RowDefinition>
    </Grid.RowDefinitions>
    <Button Name="btnAddEntry" Click="btnAddEntry_Click" Width="80" Height="40" HorizontalAlignment="Left" VerticalAlignment="Top" Content="Add Entry" Grid.Row="0">

    </Button>
<DockPanel Grid.Row="1">
                <TextBlock Text="{Binding Count, StringFormat='{}{0} Items'}" 
           DockPanel.Dock="Top"/>
        <ItemsControl ItemsSource="{Binding}" Style="{StaticResource LogViewerStyle}" DataContext="{Binding}">
            <ItemsControl.Template>
                        <ControlTemplate>
                            <ScrollViewer CanContentScroll="True">
                                <ItemsPresenter/>
                            </ScrollViewer>
                        </ControlTemplate>
                    </ItemsControl.Template>
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <VirtualizingStackPanel IsItemsHost="True"/>
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                </ItemsControl>
            </DockPanel>

</Grid>

这是测试控件的主窗口ap的代码

Here is the code for the main window ap that tests the control

mainWindow.xaml.cs

mainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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;
using ScrollingTerminalWindow;

namespace ScrollingTextBoxTestApp
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
public partial class MainWindow : Window
{
    TerminalWindow tw;
    public MainWindow()
    {
        InitializeComponent();
        tw = new TerminalWindow();
    }

    private void btn_Click(object sender, RoutedEventArgs e)
    {
        tw.AddEntry();
    }
}

}

mainwindow.xaml

mainwindow.xaml

<Window x:Class="ScrollingTextBoxTestApp.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:ScrollingTerminalWindow;assembly=ScrollingTerminalWindow"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="60"></RowDefinition>
        <RowDefinition Height="*"></RowDefinition>

    </Grid.RowDefinitions>
    <Button Name="btn" Click="btn_Click" Grid.Row="0" Content="MainPageAddEntry"></Button>
    <local:TerminalWindow Margin="10,10,0,0" Name="terminalWindow1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Grid.Row="1"/>
</Grid>

推荐答案

尝试替换此行:

tw = new TerminalWindow();

与此:

tw = terminalWindow1;

除了在XAML中定义的对象外,还创建了另一个TerminalWindow对象.您需要引用在XAML中定义的那个,然后调用其AddEntry()来查看结果.

You created another TerminalWindow object apart from the one you defined in XAML. You need to reference the one you defined in XAML then invoke its AddEntry() instead, to see the result.

这篇关于当从其控件内部调用而不是从主应用外部调用时,函数调用才起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆