Окно уведомлений при любой операции на диске C: - PullRequest
0 голосов
/ 21 мая 2011

Я создал образец для окна уведомлений в silverlight4.

Проблема, с которой я сталкиваюсь, заключается в том, что я хочу показывать окно уведомлений всякий раз, когда на моем диске Windows C: выполняется какая-либо операция (например, скопированный или удаленный файл).

Поскольку класс System.IO.FileSystemWatcher (COM + компонент) не может использоваться в silverlight, поэтому я нашел выход, используя AutomationFactory , он работает для меня, как чудо, пока я использую окно сообщения показать окно уведомления или уведомления по умолчанию, но не в случае моего собственного окна пользовательских уведомлений ..: (

Код такой -

new Thread(() =>
            {
                using (dynamic SWbemLocator = AutomationFactory.CreateObject("WbemScripting.SWbemLocator"))
                {
                    SWbemLocator.Security_.ImpersonationLevel = 3;
                    SWbemLocator.Security_.AuthenticationLevel = 4;
                    dynamic IService = SWbemLocator.ConnectServer(".", @"root\cimv2");

                    string fileSystemWatcherQuery =
                        @"SELECT * FROM __InstanceOperationEvent WITHIN 3 WHERE Targetinstance ISA 'CIM_DirectoryContainsFile' and TargetInstance.GroupComponent= 'Win32_Directory.Name=""c:\\\\""'";
                    dynamic monitor = IService.ExecNotificationQuery(fileSystemWatcherQuery);

                    Dispatcher.BeginInvoke(() => MessageBox.Show(@"Now listening to file changes on c:\"));

                    while (true)
                    {
                        dynamic EventObject = monitor.NextEvent();
                        string eventType = EventObject.Path_.Class;
                        string path = EventObject.TargetInstance.PartComponent;
                        Dispatcher.BeginInvoke((Action)delegate
                        {
                            System.Windows.NotificationWindow notify = new System.Windows.NotificationWindow();
                            notify.Height = 74;
                            notify.Width = 329;

                            CustomNotification custom = new CustomNotification();
                            custom.Header = "FileSystemWatcher";
                            custom.Text = eventType + ":" + path;
                            custom.Width = notify.Width;
                            custom.Height = notify.Height;
                            custom.Closed += new EventHandler<EventArgs>(custom_Closed);
                            notify.Content = custom;
                            notify.Show(5000);
                        });
                        Dispatcher.BeginInvoke(() => MessageBox.Show(eventType + ": " + path));
                    }
                }
            }).Start();

Всякий раз, когда я копировал файл или удалял файл из моего C:, появляется окно сообщения и появляется окно уведомления, но содержимое полностью пустое. Если я использую окно уведомлений по умолчанию вместо моего собственного CustomNotification, оно работает нормально.

То, что я предполагаю, это что-то связанное с многопоточностью, хотя не уверен .. ??

CustomNotification - это класс, производный от класса ContentConrol и имеющий два свойства зависимости, а именно: «Заголовок» и «Текст». Шаблон управления для этого я объявил в другом файле xaml, как это -

<Style TargetType="local:CustomNotification">
            <Setter.Value>
                <ControlTemplate TargetType="local:CustomNotification">
                    <Border BorderBrush="Black" BorderThickness="1">
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="7"/>
                                <RowDefinition Height="*"/>
                            </Grid.RowDefinitions>
                            <Rectangle Grid.Row="0">
                                <Rectangle.Fill>
                                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                        <GradientStop Color="#FFB9B9CC"/>
                                        <GradientStop Color="#FF9191AB" Offset="1"/>
                                    </LinearGradientBrush>
                                </Rectangle.Fill>
                            </Rectangle>

                            <Grid Grid.Row="1">
                                <Grid.Background>
                                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                        <GradientStop Color="#FFEDEDF5" Offset="0"/>
                                        <GradientStop Color="#FFC4C3D7" Offset="1"/>
                                    </LinearGradientBrush>
                                </Grid.Background>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="40"/>
                                    <ColumnDefinition Width="*"/>
                                    <ColumnDefinition Width="20"/>
                                </Grid.ColumnDefinitions>
                                <Button x:Name="closeButton" Grid.Column="2" VerticalAlignment="Top" Margin="1, 3" Width="16" Height="13">
                                    <Button.Template>
                                        <ControlTemplate TargetType="Button">
                                            <Image Source="x.png"/>
                                        </ControlTemplate>
                                    </Button.Template>
                                </Button>
                                <StackPanel Grid.Column="1" Margin="5, 7">
                                    <TextBlock Text="{TemplateBinding Header}" FontFamily="Verdana" FontWeight="Bold" FontSize="11"/>
                                    <TextBlock Text="{TemplateBinding Text}" FontFamily="Verdana" FontSize="11" TextWrapping="Wrap"/>
                                </StackPanel>
                            </Grid>
                        </Grid>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

Вот мой код класса CustomNotification -

 public class CustomNotification : ContentControl
    {
        public CustomNotification()
        {
            this.DefaultStyleKey = typeof(CustomNotification);
        }

        public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register(
            "Header",
            typeof(string),
            typeof(CustomNotification),
            new PropertyMetadata(OnHeaderPropertyChanged));

        /// <summary>
        ///   Gets or sets a value that indicates whether 
        ///   the <see cref="P:System.Windows.Controls.Label.Target" /> field is required. 
        /// </summary>
        public string Header
        {
            get
            {
                return (string)GetValue(CustomNotification.HeaderProperty);
            }

            set
            {
                SetValue(CustomNotification.HeaderProperty, value);
            }
        }

        private static void OnHeaderPropertyChanged(DependencyObject depObj, DependencyPropertyChangedEventArgs e)
        {
        }

        public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
            "Text",
            typeof(string),
            typeof(CustomNotification),
            new PropertyMetadata(OnTextPropertyChanged));

        /// <summary>
        ///   Gets or sets a value that indicates whether 
        ///   the <see cref="P:System.Windows.Controls.Label.Target" /> field is required. 
        /// </summary>
        public string Text
        {
            get
            {
                return (string)GetValue(CustomNotification.TextProperty);
            }

            set
            {
                SetValue(CustomNotification.TextProperty, value);
            }
        }

        private static void OnTextPropertyChanged(DependencyObject depObj, DependencyPropertyChangedEventArgs e)
        {
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            Button closeButton = GetTemplateChild("closeButton") as Button;
            if (closeButton != null)
            {
                closeButton.Click += new RoutedEventHandler(closeButton_Click);
            }
        }


        public event EventHandler<EventArgs> Closed;

        void closeButton_Click(object sender, RoutedEventArgs e)
        {
            EventHandler<EventArgs> handler = this.Closed;
            if (handler != null)
            {
                handler(this, EventArgs.Empty);
            }
        }

1 Ответ

0 голосов
/ 22 мая 2011

Я предполагаю, что ваш класс CustomNotification является просто пользовательским элементом управления (то есть наследуется непосредственно от UserControl)? При условии, что эта строка:

notify.Content = tb;

неправильно. Я не знаю, что такое ТБ, но оно должно быть:

notify.Content = custom;

Тогда вы увидите содержимое.

Обратите внимание, что вы должны быть осторожны, чтобы не пытаться показывать уведомление, пока другое отображается в данный момент. Вы получите исключение, поэтому вам нужно следить за этим.

Надеюсь, это поможет ...

Крис Андерсон

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...