2011年6月5日 星期日

在 WPF 如何改變 ListBox 已選擇項目的樣式?

關於這個問題我也搞了好久,以下是完整範例:

其實重點在於要改變 ListBoxItem 的 Template 屬性,然後指定 IsSelected 屬性為 True 時的樣式。


<Window x:Class="Project_DependencyProperty.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:Project_DependencyProperty"
        Title="MainWindow" Height="513" Width="526">
    <Window.Resources>
        <local:TaskCollection x:Key="Tasks"/>
        <DataTemplate DataType="{x:Type local:Task}">
            <Border BorderThickness="1" BorderBrush="Blue" Margin="2" Padding="2">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="80*"/>
                        <ColumnDefinition Width="5*"/>
                        <ColumnDefinition Width="15*"/>
                    </Grid.ColumnDefinitions>
                    <TextBlock Text="{Binding Name}" Grid.Column="0"/>
                    <TextBlock Text=":" Grid.Column="1"/>
                    <TextBlock Text="{Binding Type}" Grid.Column="2"/>
                </Grid>
            </Border>
        </DataTemplate>
        <Style TargetType="ListBoxItem" x:Key="SelectedItem">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ListBoxItem}">
                        <Border Background="Gray"
                            CornerRadius="8"
                            BorderThickness="3"
                            x:Name="LBI"
                            Margin="0" >
                            <ContentPresenter/>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsSelected" Value="true">
                                <Setter TargetName="LBI" Property="Background">
                                    <Setter.Value>Yellow</Setter.Value>
                                </Setter>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Setter Property="Background" Value="LightBlue"/>
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="Background" Value="Blue"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    <Grid>
        <ListBox HorizontalContentAlignment="Stretch" Margin="17,18,10,13"
                 Name="listBox1" FontWeight="Normal" FontStyle="Normal"
                 ItemContainerStyle="{DynamicResource SelectedItem}"
                 SelectionMode="Extended">
            <ListBox.ItemsSource>
                <Binding Source="{StaticResource Tasks}"/>
            </ListBox.ItemsSource>
        </ListBox>
        <Grid.LayoutTransform>
            <ScaleTransform ScaleX="1.5" ScaleY="1.5"/>
        </Grid.LayoutTransform>
    </Grid>
</Window>

2011年5月29日 星期日

在 WPF 中如何將 Label 的 Content 屬性繫結到父容器的 Width 屬性?

Good Question...

<Grid Width="500" Name="widthProvider">
    <Label  Height="28" Name="label1" Width="203">
        <Label.Content>
            <Binding Path="Width">
                <Binding.RelativeSource>
                    <RelativeSource Mode="FindAncestor" AncestorType="Grid" AncestorLevel="1"/>
                </Binding.RelativeSource>
            </Binding>
        </Label.Content>
    </Label>
</Grid>

2011年4月7日 星期四

Eclipse + Tomcat 單步除錯設定

  • 先下載:http://www.eclipsetotale.com/tomcatPlugin.html#A4l
  • 打開 Window/Preferences/Tomcat。
  • 指定 Tomcat Version
  • Tomcat Home (Tomcat 的安裝目錄,例:C:\Program Files\Apache Software Foundation\Tomcat 6.0)。
  • Context declaration mode:我也不知道這是啥,指定 server.xml 就行了。
  • Advanced/Tomcat base 我都用空白,不用指定,實際上我也不知道那是什麼。
  • Advanced/Launch Tomcat using Security Manager 我是不勾選。
  • Advanced/Add Java projects to Tomcat classpath
    • 在目前 workspace中,希望被 tomcat 找到的專案,通常就指定正在開發中,或是要 debug 的專案,也可以全部都選。
  • JVM Settings/JRE 這個選項一定要指定是 jdk 版本,不然會不能用。
  • JVM Settings/Classpath(Before generated classpath)
    • JDK 中沒有的,所需要的額外 jar 檔案應該都要在這指定,例如:servlet-api.jar。
  • Source Path:通常這裡列出來的應該是目前 workspace 裡面所有專案,與「Advanced/Add Java projects to Tomcat classpath」裡面列的會一樣,只是這裡有選的話,就可以單步執行程式碼了。
  • Tomcat Manager App:應該什麼都不用改吧…。 
按照上面的設定之後一定能單步執行嗎?看運氣吧...

2011年3月1日 星期二

WPF 拖放

請看下列文章 Overview:
http://msdn.microsoft.com/zh-tw/library/ms742859.aspx

這篇是範例:
http://www.wpftutorial.net/DragAndDrop.html

Drag&Drop in 6 Steps

  1. Detect a drag as a combinatination of MouseMove and MouseLeftButtonDown
  2. Find the data you want to drag and create a DataObject that contains the format, the data and the allowed effects.
  3. Initiate the dragging by calling DoDragDrop()
  4. Set the AllowDrop property to True on the elements you want to allow dropping.
  5. Register a handler to the DragEnter event to detect a dragging over the drop location. Check the format and the data by calling GetDataPresent() on the event args. If the data can be dropped, set the Effect property on the event args to display the appropriate mouse cursor.
  6. When the user releases the mouse button the DragDrop event is called. Get the data by calling the GetData() method on the Data object provided in the event args. 

Example Code:

XAML  ---------------------------------------------------------

<Window x:Class="WpfDragDrop.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="237" Width="284">
    <Grid>
        <Label Content="DragSource" Height="28" HorizontalAlignment="Left" Margin="29,12,0,0" 
               Name="label1" VerticalAlignment="Top" 
               PreviewMouseLeftButtonDown="label1_PreviewMouseLeftButtonDown" 
               PreviewMouseMove="label1_PreviewMouseMove" />
        
        <Label Content="Label" Height="28" HorizontalAlignment="Left" Margin="79,78,0,0" 
               Name="label2" VerticalAlignment="Top" Drop="label2_Drop" AllowDrop="True" />
    </Grid>
</Window>

C# ---------------------------------------------------------
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;

namespace WpfDragDrop
{
    /// <summary>
    /// MainWindow.xaml 的互動邏輯
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private Point startPoint;

        private void label1_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            startPoint = e.GetPosition(null);
        }

        private void label1_PreviewMouseMove(object sender, MouseEventArgs e)
        {
            // Get the current mouse position
            Point mousePos = e.GetPosition(null);
            Vector diff = startPoint - mousePos;

            if (e.LeftButton == MouseButtonState.Pressed &&
                Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance &&
                Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance)
            {
                //// Get the dragged ListViewItem
                //ListView listView = sender as ListView;
                //ListViewItem listViewItem =
                //    FindAnchestor<ListViewItem>((DependencyObject)e.OriginalSource);

                //// Find the data behind the ListViewItem
                //object contact = (object)listView.ItemContainerGenerator.
                //    ItemFromContainer(listViewItem);

                // Initialize the drag & drop operation
                DataObject dragData = new DataObject(DataFormats.Text, label1.Content);
                DragDrop.DoDragDrop(label1, dragData, DragDropEffects.Move);
            }
        }

        private void label2_Drop(object sender, DragEventArgs e)
        {
            label2.Content = e.Data.GetData(DataFormats.Text);
        }

        private static T FindAnchestor<T>(DependencyObject current) where T : DependencyObject
        {
            do
            {
                if (current is T)
                {
                    return (T)current;
                }
                current = VisualTreeHelper.GetParent(current);
            }
            while (current != null);
            return null;
        }
    }
}


2011年2月13日 星期日

下面是我花了一天的研究成果!

下面這段程式是用 C++ 啟動 .Net Runtime 的範例,利用這範例可以寫出偵測戶端有沒有安裝 .Net Framework 的前導程式。我知道很難理解,由其是沒寫過 C++ 的人...


 參考來源:http://msdn.microsoft.com/zh-tw/library/dd380851.aspx

#include "stdafx.h"

#include <iostream>
#include <Metahost.h>
//#include <mscoree.h>
#include <CorError.h>

#pragma comment(lib, "mscoree.lib")

// LPCWSTR 不可變的寬字元。
// LPWSTR 可變的寬字元,要用 malloc 初始化。

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
ICLRMetaHost *pMetaHost = NULL;
//ICLRMetaHostPolicy *pMetaHostPolicy = NULL;
//ICLRDebugging *pCLRDebugging   = NULL;
HRESULT hr;

hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost,
(LPVOID*)&pMetaHost);
//hr = CLRCreateInstance (CLSID_CLRMetaHostPolicy, IID_ICLRMetaHostPolicy,
// (LPVOID*)&pMetaHostPolicy);
//hr = CLRCreateInstance (CLSID_CLRDebugging, IID_ICLRDebugging,
// (LPVOID*)&pCLRDebugging);

ICLRRuntimeInfo *clr = NULL;
hr = pMetaHost->GetRuntime(L"v4.0.30319", IID_ICLRRuntimeInfo,(LPVOID *)&clr);
ICLRRuntimeHost *runtime= NULL;

hr = clr->GetInterface(CLSID_CLRRuntimeHost , IID_ICLRRuntimeHost, (LPVOID*)&runtime);

hr = runtime->Start();

//執行 .Net Manage 程式。
//DWORD *retval = 0;
//hr = runtime->ExecuteInDefaultAppDomain(L"C:\\Users\\Yaoming\\Documents\\visual studio 2010\\Projects\\ClrApp\\ClrApp\\bin\\Debug\\ClrApp.dll"
// ,L"ClrApp.Program",L"AppMain",L"",retval);

//取得已安裝的 .Net Runtime 版本字串。
IEnumUnknown *setups = NULL;
hr = pMetaHost->EnumerateInstalledRuntimes(&setups);
ICLRRuntimeInfo *rt; 
ULONG actual;
while((hr = setups->Next(1, (IUnknown**)&rt, &actual)) == S_OK)  
{
DWORD buffer = 20;
LPWSTR ver = (LPWSTR)malloc(buffer * sizeof(LPWSTR));
hr = rt->GetVersionString(ver,&buffer);

if(hr == S_OK)
cout << ver << endl;
else
cout << "Get version fail." << endl;

hr = pMetaHost->GetRuntime(ver, IID_ICLRRuntimeInfo,(LPVOID *)&clr);

if(hr == S_OK)
cout << ver << endl;
else
cout << "Get runtime fail." << endl;
}

if(hr == S_OK)
cout << "S_OK" << endl;
else if (hr == HOST_E_CLRNOTAVAILABLE)
cout << "Clr Not available" << endl;
else if (hr == HOST_E_TIMEOUT)
cout << "Time out " << endl;
else if(hr == HOST_E_NOT_OWNER)
cout << "Not owner" << endl;
else if(hr == HOST_E_ABANDONED)
cout << "abandoned" << endl;
else
cout << "Fail" << endl;

system("pause");

return 0;
}