Storyboard で、textBoxの TranslateTransform を変更

SetTargetPropertyあたりのプログラミングで、どのように表記すればいいのかが分からず難しい。

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;

namespace wpfsbtest1
{
    /// <summary>
    /// Window1.xaml の相互作用ロジック
    /// </summary>
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
            Play1();
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            translateTransform1.BeginAnimation(TranslateTransform.XProperty, daukf);
        }

        Storyboard myStoryboard1 = new Storyboard();

        DoubleAnimationUsingKeyFrames daukf = new DoubleAnimationUsingKeyFrames();

        TranslateTransform translateTransform1 = new TranslateTransform();
        private void Play1()
        {
            textBox1.RenderTransform = translateTransform1;

            SplineDoubleKeyFrame sdkf1 = new SplineDoubleKeyFrame(0, KeyTime.FromTimeSpan(new TimeSpan(0, 0, 0)));
            SplineDoubleKeyFrame sdkf2 = new SplineDoubleKeyFrame(200, KeyTime.FromTimeSpan(new TimeSpan(0, 0, 3)));

            daukf.BeginTime = new TimeSpan(0, 0, 0);
            daukf.Duration = new TimeSpan(0, 0, 3);
            daukf.KeyFrames.Add(sdkf1);
            daukf.KeyFrames.Add(sdkf2);

            Storyboard.SetTargetName(daukf, this.textBox1.Name);
            Storyboard.SetTargetProperty(daukf, new PropertyPath(TranslateTransform.XProperty));

            myStoryboard1.Children.Add(daukf);
        }
    }
}

Storyboard で textBoxの幅を変更

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Animation;

namespace wpfsbtest1
{
    /// <summary>
    /// Window1.xaml の相互作用ロジック
    /// </summary>
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
            Play1();
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            myStoryboard1.Begin(button1);

        }

        Storyboard myStoryboard1 = new Storyboard();
        DoubleAnimation myDoubleAnimation1 = new DoubleAnimation();

        private void Play1()
        {
            myDoubleAnimation1.From = 100;
            myDoubleAnimation1.To = 300;
            myDoubleAnimation1.Duration = new Duration(TimeSpan.FromMilliseconds(3000));

            Storyboard.SetTargetName(myDoubleAnimation1, this.textBox1.Name);
            Storyboard.SetTargetProperty(myDoubleAnimation1, new PropertyPath(TextBox.WidthProperty));

            myStoryboard1.Children.Add(myDoubleAnimation1);
        }
    }
}

Twitter Client

かずきのBlog http://blogs.wankuma.com/kazuki/archive/2008/04/24/135133.aspx に、 Twitter Client のコードが載っていた。

面白そうなので、ちょっとビルドしてみたら、簡単にデータが取れてしまった。

コードをイベントハンドラを呼び出すように少し変えたので、メモ。

using System;
using System.Collections.Generic;
using System.Net;  
using System.Text;
using System.Linq;
using System.Xml.Linq;

namespace t1
{
    public struct Account
    {
        public string UserID { get; set; }
        public string Password { get; set; }
    }

    public class TwitterStatus
    {
        public long ID { get; set; }
        public string Text { get; set; }
    }  

    class TwitterClient
    {
        private readonly string PUBLIC_TIMELINE_URL = "http://api.twitter.com/statuses/public_timeline.xml";
        private readonly string FRIENDS_TIMELINE_URL = "http://api.twitter.com/1/statuses/friends_timeline.xml";

        public Account UserAccount { get; set; }

        public void GetFriendsTimeline()
        {
            var client = new WebClient();
            // 認証情報セット  
            client.Credentials = CreateNetworkCredential();

            // GET!  
            var data = client.DownloadData(FRIENDS_TIMELINE_URL);

            var xml = XElement.Parse(Encoding.UTF8.GetString(data));

            // ID, Textを抜きだす  
            var result = from status in xml.Descendants("status")
                         select new TwitterStatus
                         {
                             ID = long.Parse(status.Element("id").Value),
                             Text = status.Element("text").Value
                         };
            DataReceived(result.ToList(), null);
        }

        public delegate void EventHandler(Object sender, EventArgs e);

        public event EventHandler DataReceived;

        private NetworkCredential CreateNetworkCredential()
        {
            return new NetworkCredential(UserAccount.UserID, UserAccount.Password);
        }
    }
}

呼び出しは、

private void button1_Click(object sender, RoutedEventArgs e)
{
    string user = ***;
    string pass = ***;

    var twitter = new TwitterClient
    {
        UserAccount = new Account { UserID = user, Password = pass }
    };

    twitter.DataReceived += new TwitterClient.EventHandler(twitter_DataReceived);
    twitter.GetFriendsTimeline();
}

void twitter_DataReceived(object sender, EventArgs e)
{
    IList<TwitterStatus> lis = (IList<TwitterStatus>)sender;

    foreach (var r in lis)
    {
   string str = string.Format("{0}:{1}", r.ID, r.Text);
   textBox1.Text += str + "\n";
    }
}

実行結果: ここまで、1時間かからないで来てしまう。
バックグラウンドワーカー入れて、タイマー入れて、文字列をあーして、こーして、あっという間にクライアントができてしまいそう。
C# 偉大すぎる。

image

Twitter Screensaver for Visual Studio 2010

http://visualstudiogallery.msdn.microsoft.com/ja-JP/d48ac618-3cdf-4f1d-8366-316d508fb6d6

にTwitter Screensaver (CS)(Free) の記事があった。

Screensaver.Template.CS.vsix をダウンロードし、実行すると、次のような拡張機能インストーラが起動される。

image

インストールボタンを押すと、次のようにインストールが完了する。

image 

または、拡張機能マネージャーのオンライン ギャラリーに、さまざまなテンプレートなどがあり、ダウンロードできるようになっている。その中から、Twitter Screensaver (CS)を選び、ダウンロードボタンを押し、インストールする。

image

しかし、このままだと拡張機能マネージャーからみると”無効”になっていて、テンプレートに現れない。ユーザーごとの有効・・・というメッセージに従って、有効にする。

image 

新しいプロジェクトのインストールされたテンプレートに、”Twitterscreensaver”が現れる。

image

そのままビルドすると、twitter screensaver が動いてしまう・・・

スクリーンセーバーとしてインストールするには、”Screensaver1.exe.scr” を右クリックして、インストールすれば OK となる。

設定は、ハッシュタグだけど、こんな感じになる。

image

プロセスモニタ

どこかで見たことのあるようなものをWPFで作ってみた。

image

簡単に作れるだろうと思っていたのだけど、いくつか、ハマり中。

1.プロセスの情報を取るいいI/Fが見つからない。System.Diagnostics.Process.GetProcesses() だと、プロセッサタイムが取得できないので、しかたなしにWMIでプロセスの情報を取っているのだけれど、結構重くって、CPUパワーが食われまくり。パフォーマンスカウンターを全プロセス分持つのも芸がないし、Win32 SDKを叩くか?? .NETで、いい方法ない?

2.画面のリサイズもフォントサイズとPolygon の関係をちゃんと考えないといけないので、意外と難しい。

3.おまけに6角形にレイアウトするのも面倒。誰か、HexaFlowコントロール作ってくれないかな w

でも、こんな感じで http://uchukamen.com/pmon/publish.htm 意外と見ていて面白い。

PS. LINQ は偉大だ。もう LINQ 無しでは生きていけない体になってしまった。

WPF ユーザーコントロール

<UserControl x:Class="WpfApplication6.Cell"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        >
    <Grid >
    <Polygon Name="Polygon" Margin="5 5 5 5"
    Points="25,0 75, 0 100,43 75,86 25, 86 0 43"
    Stroke="Purple"
    StrokeThickness="2">
            <Polygon.Fill>
                <SolidColorBrush Color="Red" Opacity="0.8"/>
            </Polygon.Fill>
        </Polygon>

        <Label Name="label1" HorizontalContentAlignment="Center" Margin="6,15,6,0">Label</Label>
        <Label Name="label2" HorizontalContentAlignment="Center" Margin="4,47,8,21" >Label</Label>
    </Grid>

</UserControl>

用途は・・・

Process 情報の取得に関するメモ2

WMI を使用して Process 情報を取得する際に LINQ を使用しようとすると

ManagementObjectSearcher query1 = new ManagementObjectSearcher("SELECT * FROM Win32_Process");
ManagementObjectCollection queryCollection1 = query1.Get();

var query = from proc in queryCollection1 select proc;
foreach (var process in query)
{
   …
}

エラー    1    ソース型 ‘System.Management.ManagementObjectCollection’ のクエリ パターンの実装が見つかりませんでした。’Select’ が見つかりません。範囲変数 ‘proc’ の型を明示的に指定してください。    C:\Users\uchukamen\Documents\Visual Studio 2008\Projects\WpfApplication6\WpfApplication6\Window1.xaml.cs    140    38    WpfApplication6

というエラーになる。

回避方法は、範囲変数 proc の型を明示的に指定するために、queryCollection1.Cast<ManagementObject>()  としてあげるとうまくいった。うむむむむ・・・

ManagementObjectSearcher query1 = new ManagementObjectSearcher("SELECT * FROM Win32_Process");
ManagementObjectCollection queryCollection1 = query1.Get();

var query = from proc in queryCollection1.Cast<ManagementObject>() select proc;
foreach (var process in query)
{
    Console.WriteLine(process["ProcessId"] + ":");
    Console.WriteLine(process["Name"] + ":");
    Console.WriteLine(process["KernelModeTime"] + ":");
    Console.WriteLine(process["UserModeTime"] + ":");
}

——

もうちょっと見やすく?すると、IEnumerable<ManagementObject> にキャストしてくれるということ。

ManagementObjectSearcher query1 = new ManagementObjectSearcher("SELECT * FROM Win32_Process");
ManagementObjectCollection queryCollection1 = query1.Get();
IEnumerable<ManagementObject> procQuery = queryCollection1.Cast<ManagementObject>();

var procs = from proc in procQuery select proc;

foreach (var process in procs)
{
    Console.WriteLine(process["ProcessId"] + ":");
    Console.WriteLine(process["Name"] + ":");
    Console.WriteLine(process["KernelModeTime"] + ":");
    Console.WriteLine(process["UserModeTime"] + ":");
}

Process 情報の取得に関するメモ

Visual Studio 2008 , Vista で、GetProcesses() でプロセス情報を取得する際に、TotalProcessorTime などプロセッサタイムを取得しようとすると、Win32Exception により取得できない。なぜ??

var query = from proc in System.Diagnostics.Process.GetProcesses()
            orderby proc.Id
            select new
            {
                Id = proc.Id,
                processName = proc.ProcessName,
                TotalProcessorTime = proc.TotalProcessorTime
            };

foreach (var process in query)
{
    Console.WriteLine(process.Id + ":");
    Console.WriteLine(process.processName + ":");
    Console.WriteLine(process.TotalProcessorTime + ":");
}

—————–

WMI を使用すれば、取得可能。

ManagementObjectSearcher query1 = new ManagementObjectSearcher("SELECT * FROM Win32_Process");
ManagementObjectCollection queryCollection1 = query1.Get();

foreach (ManagementObject mo in queryCollection1)
{
    Console.WriteLine(mo["ProcessId"] + "\t" + mo["Name"] + "\t" +
        ":\tKernelModeTime=" + mo["KernelModeTime"] +  // in 100 nanosecond units
        ":\tUserModeTime=" + mo["UserModeTime"]);   // in 100 nanosecond units
}