アイデアは、すべてのユーザーのリストから、個人的に(ドラッグアンドドロップを使用して)ユーザーを2つのグループに分類できるということです。 さらに、否定的なカルマを持つユーザーはホワイトリストに追加できません。
しかし、ポイントに近い。 猫をお願いします。
だから、はじめに。
箱から出してすぐにドラッグアンドドロップ機能を使用して開始することはできません(すべてを自分で実装する必要があります)が、私たちの生活を楽にするために、MicrosoftのSilverlightチームの特別な訓練を受けた人は、 Silverlight Toolkitのすべてを既に実装しています 。
この機能は、いくつかの基本的なコントロール(ユーザーコントロール)のラッパーの形で、コントロールの名前+ DragDropTarget ( ListBoxの場合はListBoxDragDropTarget )で表示されます。 ドラッグアンドドロップが実演されるのは、ListBoxまたはむしろ複数のListBoxの例です。
新しいSilverlightアプリケーションを作成しましょう。
私はそれをDragAndDropTestAppと呼びましたが、実際にはまったく問題ではありません。
次のダイアログボックスで、すべてをそのままにして[OK]をクリックします。
ツールキットへのリンクをすぐに追加します。
既にダウンロードおよびインストールされていると想定されます。
次の名前空間をMainPage.xamlに追加します。
xmlns:toolkit= "clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Toolkit"
xmlns:my= "clr-namespace:DragAndDropTestApp"
* All source code (under and below) was highlighted with Source Code Highlighter .
ツールキット上。 そして、アプリケーションが存在する名前空間。
xamlをスケッチします。
3つのリストはそれぞれ、次のマークアップで表されます。
< TextBlock
Text ="Users:"
Style ="{StaticResource Header}" />
< toolkit:ListBoxDragDropTarget
Grid . Row ="1"
HorizontalContentAlignment ="Stretch"
VerticalContentAlignment ="Stretch" >
< ListBox >
< ListBox.ItemTemplate >
< DataTemplate >
< my:UCUser />
</ DataTemplate >
</ ListBox.ItemTemplate >
</ ListBox >
</ toolkit:ListBoxDragDropTarget >
要素のリストのタイトルを含むTextBox(App.xamlで手を出したすべてのスタイルを含む)。 そして、実際には、ListBoxDragDropTargetにラップされたListBox自体。 ItemTemplateは、ユーザーを表示するために再定義されます。 UCUserは私自身のコントロールです。 内部には超自然的なものは何もありません、自分で見てください。
- < グリッド
- x:名前 = "LayoutRoot"
- 背景 =「透明」 >
- < Grid.ColumnDefinitions >
- < ColumnDefinition Width = "Auto" />
- < ColumnDefinition Width = "4 *" />
- < ColumnDefinition Width = "6 *" />
- </ Grid.ColumnDefinitions >
- < Grid.RowDefinitions >
- < RowDefinition Height = "Auto" />
- < RowDefinition Height = "Auto" />
- </ Grid.RowDefinitions >
- < 画像
- ソース = "../ Images / gnome_face_devilish.png"
- 幅 = "48"
- 高さ = "48"
- マージン = " 15、0、20、0 "
- グリッド RowSpan = "2" />
- < TextBlock
- テキスト =「ニックネーム:」
- グリッド 列 = "1" />
- < TextBlock
- テキスト =「{バインディングパス=ニックネーム、モード= OneWay}」
- グリッド 列 = "2"
- FontWeight = "太字" />
- < TextBlock
- テキスト = "Karma:"
- グリッド 行 = "1"
- グリッド 列 = "1" />
- < TextBlock
- テキスト =「{Binding Path = Karma、Mode = OneWay}」
- グリッド 行 = "1"
- グリッド 列 = "2"
- FontWeight = "太字" />
- </ グリッド >
ソースが画像に設定され、データバインディング(バインディング)が登録されます。
ところで、ユーザーには別のクラスがあります。 彼の見解は次のとおりです。
public class User
{
public string NickName { get ; set ; }
public int Karma { get ; set ; }
}
次に、各リストのコレクションを作成し、ユーザーの読み込みをシミュレートします。
- パブリック 部分 クラス MainPage:UserControl
- {
- パブリック MainPage()
- {
- InitializeComponent();
- this .DataContext = this ;
- InitializeCollections();
- LoadUsers();
- }
- //コレクションを宣言します
- public ObservableCollection <User> Users { get ; セット ; }
- public ObservableCollection <User> WhiteList { get ; セット ; }
- public ObservableCollection <User> BlackList { get ; セット ; }
- //コレクションを初期化します
- private void InitializeCollections()
- {
- ユーザー= 新しい ObservableCollection <ユーザー>();
- WhiteList = new ObservableCollection <User>();
- BlackList = new ObservableCollection <User>();
- }
- // Usersコレクションへのデータの読み込みをシミュレートするメソッド
- private void LoadUsers()
- {
- var r = new Random ();
- //ランダムなカルマ値を持つ20人のユーザーを追加します。
- for ( int i = 1; i <21; i ++)
- {
- var newUser = 新しいユーザー
- {
- NickName = "ユーザー名" + i
- カルマ= r。次(200)-100
- };
- Users.Add(newUser);
- }
- }
- }
MainPageのDataContextとして、 MainPage自体をインストールします。 これは、データに簡単に添付できるようにするためです。 次のようになります。
< ListBox ItemsSource ="{Binding Path=Users, Mode=TwoWay}" >
ドラッグアンドドロップが機能するには、最後のタッチがありません。
AllowDrop ="True"
このプロパティをtrueに設定することにより、要素がドラッグアンドドロップを使用してデータを受け入れることができます。 さらに、ListBoxとListBoxDragDropTargetの両方にインストールできます。
起こったことは次のとおりです。
これで、ネガティブカルマを持つユーザーを任意のリストにドラッグできます。
計画によると、ホワイトリストへのドラッグを禁止する必要があります。
最初に、Drag-n-Drop'eのときに生成されるイベントを見てみましょう。
DragEnterは、ドラッグされたコンテナが宛先要素の境界を越えると発生します (DragOverイベントの前に発生します)。
DragLeave-ドラッグされたコンテナはソース要素からプルされました。
DragOver-ドラッグされたコンテナが宛先要素上を移動すると起動します。
ドロップ -ドラッグされたコンテナは、宛先要素に「ドロップ」されました。
ホワイトリストのDragEnterイベントハンドラーを追加します 。
- < ツールキット:ListBoxDragDropTarget
- AllowDrop = "True"
- グリッド 行 = "1"
- グリッド 列 = "1"
- HorizontalContentAlignment = "ストレッチ"
- VerticalContentAlignment = "ストレッチ"
- DragEnter = "ListBoxDragDropTarget_DragEnter" >
- < リストボックス
- ItemsSource = "{Binding Path = WhiteList、Mode = TwoWay}"
- x:名前 = "lbWhiteList" >
- < ListBox.ItemTemplate >
- < DataTemplate >
- < my:UCUser />
- </ DataTemplate >
- </ ListBox.ItemTemplate >
- </ リストボックス >
- </ ツールキット:ListBoxDragDropTarget >
そして、ListBoxに名前を付けると、便利になります。
ハンドラー自体:
- private void ListBoxDragDropTarget_DragEnter( object sender、Microsoft.Windows.DragEventArgs e)
- {
- //形式を見つけました
- var dataFormat = e.Data.GetFormats()[0];
- // ItemDragEventArgs形式のオブジェクトを取得しました
- var dragEventArgs = e.Data.GetData(dataFormat) as ItemDragEventArgs;
- //ドラッグ可能なアイテムのコレクションを取得しました
- SelectionCollection sc = SelectionCollection としての dragEventArgs.Data;
- //コレクション内の各アイテムを確認します
- foreach (scのvar item)
- {
- //ドラッグされたアイテム(ユーザー)の少なくとも1つに負のカルマがある場合
- //これらのアイテムをホワイトリストに追加することを禁止します。
- if ((item.Item as User).Karma <0)
- {
- lbWhiteList.AllowDrop = false ;
- 休憩 ;
- }
- }
- }
DragEventArgs.Dataは、対応するドラッグイベントに関連付けられたデータを含むIDataObjectを返します。 ただし、データに直接アクセスすることはできず、非公開としてマークされます。
このデータを取得するには、 GetData()メソッドを使用します。このメソッドは、パラメーターとして渡された形式でデータを返します(形式は文字列または型として指定できます)。 また、 GetFormats()メソッドを使用してフォーマットを確認できます。
結果は、 ItemDragEventArgsクラスのインスタンスです。 このクラスには、UIElementのドラッグイベントを記述する情報が含まれます。 既にドラッグ可能なコンテナに直接関連付けられているDataプロパティがあります。 このオブジェクトをSelectionCollectionに持ってきます。
ここでは、複数のアイテムを一度にドラッグアンドドロップできるため、コレクションが使用されます。
(これは非常に簡単に確認できます。ListBoxの場合、 SelectionModeプロパティをMultipleに設定します)。
コレクション全体を実行し、ドラッグされたユーザーの中に否定的なカルマを持つ人がいるかどうかを確認することは残っています。 ある場合は、ホワイトリストに「ドロップ」することを禁止します。
MouseLeaveイベントハンドラーでAllowDropを以前の値(True)に戻すことができます。
最後に、ドラッグアンドドロップを使用して単一のリスト内のアイテムを並べ替える機能を実現するには、 ItemsPanelのテンプレートを再定義するだけで十分です 。
< ListBox.ItemsPanel >
< ItemsPanelTemplate >
< StackPanel />
</ ItemsPanelTemplate >
</ ListBox.ItemsPanel >
ここからプロジェクトをダウンロードできます。