C# WPF Tips

Windowsフォームプログラミング、WPFプログラミング゙のTipsを紹介します。極力、実務に役立つように作成しました


8.ListBoxにWクリック実装(引数あり)

戻る

Binding SelectedItem指定

「7.ListBoxにWクリック実装」に加えて、ListBoxの引数としてCommandParameterを使用して、予約語のSelectedItemをバインドします。SelectedItemは言葉どおりで、選択されている行の値が入っています。

起動時

クリックすると拡大します


下記がテキストボックスとリストボックスのZAMLです。


View

<ccl:CustomChromeWindow 
        x:Class="LivetWPFChromeHelpDesk1.Views.Window15"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:shell="http://schemas.microsoft.com/winfx/2006/xaml/presentation/shell"
        xmlns:ccl="clr-namespace:CustomChromeLibrary;assembly=CustomChromeLibrary"                                  
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
        xmlns:l="http://schemas.livet-mvvm.net/2011/wpf"
        xmlns:core="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions"      
        xmlns:v="clr-namespace:LivetWPFChromeHelpDesk1.Views"
        xmlns:vm="clr-namespace:LivetWPFChromeHelpDesk1.ViewModels"    
        WindowStartupLocation="CenterScreen"
        Title="Window15" Height="714" Width="1035">

    <shell:WindowChrome.WindowChrome>
        <shell:WindowChrome
            ResizeBorderThickness="6"
            CaptionHeight="43"
            CornerRadius="0,0,0,0"
            GlassFrameThickness="0">
        </shell:WindowChrome>
    </shell:WindowChrome.WindowChrome>

    <Window.Resources>
        <ResourceDictionary>
            <vm:XComboBoxEmptyItemConverter x:Key="XComboBoxEmptyItemConverter"/>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="/Resources/Styles.xaml"/>
                <ResourceDictionary Source="/Resources/Styles2.xaml"/>
                <ResourceDictionary Source="/Resources/StylesBG.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>

    <Window.DataContext>
        <vm:ViewModel15/>
    </Window.DataContext>

    <i:Interaction.Triggers>

        <l:InteractionMessageTrigger 
            MessageKey="MessageKey16" Messenger="{Binding Messenger}">
            <l:TransitionInteractionMessageAction
                WindowType="{x:Type v:Window16}" Mode="Modal"/>
        </l:InteractionMessageTrigger>

        <!--WindowのContentRenderedイベントのタイミングでViewModelのInitializeメソッドが呼ばれます-->
        <i:EventTrigger EventName="ContentRendered">
            <l:LivetCallMethodAction MethodTarget="{Binding}" MethodName="Initialize"/>
        </i:EventTrigger>

        <!-- 下記がないと、タスクバーが1つにならない -->
        <i:EventTrigger EventName="Loaded">
            <i:InvokeCommandAction Command="{Binding Path=Loaded}" 
                                   CommandParameter="{Binding Mode=OneTime,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}}"/>
        </i:EventTrigger>

        <!--  Activatedを設定する -->
<!--
        <i:EventTrigger EventName="Activated" >
            <i:InvokeCommandAction Command="{Binding Activated}" />
        </i:EventTrigger>
-->

        <i:EventTrigger EventName="Closing">
            <i:InvokeCommandAction Command="{Binding Path=Closing}"
                                   CommandParameter="{Binding Mode=OneTime,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}}"/>
        </i:EventTrigger>

        <l:InteractionMessageTrigger MessageKey="Close" Messenger="{Binding Messenger}">
            <l:WindowInteractionMessageAction/>
        </l:InteractionMessageTrigger>

    </i:Interaction.Triggers>

    <!-- Grid-1 -->
    <Grid>

        <!-- WindowChrome Start  -->
        <Border  Grid.RowSpan="2" BorderThickness="3" BorderBrush="Black">
            <Border.Background>
                <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
                    <GradientStop Color="Black" Offset="0" />
                    <GradientStop Color="Black" Offset="1" />
                </LinearGradientBrush>
            </Border.Background>
        </Border>

        <Border  BorderThickness="3,3,3,1" BorderBrush="Black" Margin="{Binding Path=CaptionButtonMargin}">
            <Border.Background>
                <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
                    <GradientStop Color="Black" Offset="0" />
                    <GradientStop Color="Black" Offset="1" />
                </LinearGradientBrush>
            </Border.Background>
            <!--Window Icon and Title-->
            <StackPanel Orientation="Horizontal" Margin="0" VerticalAlignment="Top">
                <TextBlock Text=" Help Desk" FontFamily="Calibri" FontWeight="Bold" FontSize="26" Foreground="Blue" />
            </StackPanel>
        </Border>
        <ccl:CaptionButtons />
        <!-- WindowChrome End  -->

        <!-- Grid-2 -->
        <!--Content-->
        <Grid Grid.Row="1">

            <!-- ★★★ -->
            <Grid>
                <TextBox Text="{Binding Path=txt本日}" TextAlignment="Center" 
                    Foreground="White" Background="Black"
                    Height="17" HorizontalAlignment="Center"  Name="txt本日" 
                    VerticalAlignment="Top" Width="81" Margin="809,3,123,0" />

                <ListBox  x:Name="listBox1"
                    ItemsSource="{Binding StaffListView}" 
                    Foreground="White" Background="Black"  
                    HorizontalContentAlignment="Stretch" Margin="69,87,0,478" 
                    HorizontalAlignment="Left" Width="186" >
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding}">
                        <TextBlock.InputBindings>
                            <MouseBinding Gesture="LeftDoubleClick"                                           
                                  Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type ListBox}}, Path=DataContext.GotoCommand16}"
                                  CommandParameter="{Binding SelectedItem, ElementName=listBox1}" />                                                          
                        </TextBlock.InputBindings>
                            </TextBlock>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>

                <TextBox Text="{Binding Path=txtMessage, Mode=TwoWay}"  
                        Foreground="White" Background="Black" Height="24" 
                        VerticalContentAlignment="Center" HorizontalAlignment="Left" 
                        VerticalAlignment="Top" Width="160" Margin="277,87,0,0" />


            </Grid>
            <!-- ★★★ -->

        </Grid>
    </Grid>
</ccl:CustomChromeWindow>


ViewModelは下記の通りです。


ViewModel

using System;
using System.Collections.Generic;
using System.Linq;

//INotifyPropertyChanged
//PropertyChanged
using System.ComponentModel;

//参照設定が必要
//using System.Configuration;

using Livet;
using Livet.Commands;
using Livet.Messaging;
//CloseCommand
using Livet.Messaging.Windows;

//ICommand
using System.Windows.Input;

//MessageBox
using System.Windows;

// ListCollectionView
using System.Windows.Data;

using LivetWPFChromeHelpDesk1.Models;
using LivetWPFChromeHelpDesk1.Views;
using LivetWPFChromeHelpDesk1.ViewModels;

namespace LivetWPFChromeHelpDesk1.ViewModels
{
    class ViewModel15 : ViewModel
    {
        #region 変更通知プロパティ
        //-----------------------------------------------
        private string _PersonName;
        public string PersonName
        {
            get { return _PersonName; }
            set
            {
                _PersonName = value;
                RaisePropertyChanged("PersonName");
            }
        }
        //
        public string txt本日 { get; set; }
        //
        private string _txtMessage;
        public string txtMessage
        {
            get { return _txtMessage; }
            set
            {
                _txtMessage = value;
                RaisePropertyChanged("txtMessage");
            }
        }
        #endregion

        Window win = null;
        public ViewModel15()
        {
            Loaded = new Livet.Commands.ListenerCommand<Window>((w) =>
            {
                if (NeedHideOwner && w.Owner != null && w.Owner.Visibility == Visibility.Visible)
                {
                    win = w;
                    //w.Owner.Hide();
                }
            });
            /*
                        Closing = new Livet.Commands.ListenerCommand<Window>((w) =>
                        {
                            if (NeedHideOwner && w.Owner != null)
                            {
                                w.Owner.Show();
                            }
                        });
            */
            //Initialize()では表示されない
            txt本日 = Convert.ToString(DateTime.Today.ToShortDateString());
        }
        public bool NeedHideOwner { get; set; }
        public ICommand Loaded { get; private set; }
        //  public ICommand Closing { get; private set; }

        public void Initialize()
        {
            if (win != null) win.Owner.Hide();


            //★ListCollectionView 5-2
            this.StaffList = new List<string>();

            GetPersonData();

            //★ListCollectionView 5-4
            this.StaffListView = new ListCollectionView(this.StaffList);
            this.StaffListView.CurrentChanged += StaffListView_CurrentChanged;
            //下記のRefreshでListBoxへバインドを実行させます
            this.StaffListView.Refresh();
        }


        #region StaffListView 社員一覧(ComboBox)
        //★ListCollectionView 5-1
        private List<string> StaffList;

        /// <summary>
        /// 社員一覧(ListBox)
        /// </summary>
        private ListCollectionView _StaffListView;
        public ListCollectionView StaffListView
        {
            get
            { return _StaffListView; }
            set
            {
                if (_StaffListView == value)
                    return;
                _StaffListView = value;
                RaisePropertyChanged("StaffListView");
            }
        }
        //
        void StaffListView_CurrentChanged(object sender, EventArgs e)
        {
            this.StaffListView.Refresh();
            //
            var lv = sender as ICollectionView;
            if (lv.CurrentPosition < 0)
            {
                System.Diagnostics.Trace.WriteLine("選択無し");
                return;
            }
            txtMessage = lv.CurrentItem as string;
        }
        #endregion

        #region GetDataCommandコマンド
        public void GetPersonData()
        {
            this.StaffList.Add("");
            this.StaffList.Add("小堺 一機");
            this.StaffList.Add("柳葉 敏郎");
            this.StaffList.Add("吉田 栄作");
            this.StaffList.Add("長井 秀和");
            this.StaffList.Add("竹内 力");
            this.StaffList.Add("宮崎 駿");
            this.StaffList.Add("小池 徹平");
            this.StaffList.Add("高橋 由美子");
            this.StaffList.Add("岡本 真夜");
            this.StaffList.Add("山口 達也");
        }
        #endregion

        #region GotoCommand16
        ListenerCommand<string> _GotoCommand16;
        public ListenerCommand<string> GotoCommand16
        {
            get
            {
                if (_GotoCommand16 == null)
                {
                    _GotoCommand16 = new ListenerCommand<string>(GetPersonName, () => true);
                }
                return _GotoCommand16;
            }
        }
        void GetPersonName(string str)
        {
            if (str == null)
            {
                Messenger.Raise(new InformationMessage("Cancel", "Error", MessageBoxImage.Error, "Info"));
                return;
            }

            if (str != null && str.Length > 0)
            {
                Messenger.Raise(new TransitionMessage(new ViewModel16(str) { NeedHideOwner = true }, "MessageKey16"));
            }
        }
        #endregion
    }
}