2016-10-01 4 views
0

Я пытаюсь создать диалог WPF для настройки расписания семинара. На левой стороне есть список с одним столбцом для имен учителей. На правой стороне есть список с шестью колонками, один для мастерских, и остальные пять столбцов для дней с понедельника по пятницу.WPF ListView Drop, получающий ячейку

| Учитель | | Семинар | Пн | Tue | Ср | Thu | Пт |

A    WS-1   A B 
B    WS-2  C 
C    WS-3       B 

Пользователь должен настроить расписание путем перетаскивания, например. учитель C учит мастерской WS-2 в понедельник.

В WinForms было простое задание получить ячейку сбрасывания, но я не нашел способ получить это в WPF .

Вот раздел кода xaml.

<ListView Name="_LV_Teacher" 
       SelectionMode="Single" 
       ItemsSource="{Binding}"> 
    <ListView.View> 
     <GridView> 
      <GridViewColumn 
       DisplayMemberBinding="{Binding Path=Id}"   
       Width="0"/> 
      <GridViewColumn 
       DisplayMemberBinding="{Binding Path=TeachersName}" Header="Teacher"/> 
     </GridView> 
    </ListView.View> 
</ListView> 

<ListView Name="_LV_Schedule" 
      ItemsSource="{Binding}" 
      AlowDrop="True" 
      Drop="_LV_Teacher_Drop" > 
    <ListView.View> 
     <GridView> 
      <GridViewColumn 
      DisplayMemberBinding="{Binding Path=WorkshopId}" Width="0"/> 
      <GridViewColumn Header="Monday"/> 
      <GridViewColumn Header="Tuesday"/> 
      <GridViewColumn Header="Wednesday"/> 
      <GridViewColumn Header="Thursday"/> 
      <GridViewColumn Header="Friday"/> 
     </GridView> 
    </ListView.View> 
</ListView> 
+0

Отметьте свой ответ как правильный ответ. http://stackoverflow.com/help/someone-answers – AnjumSKhan

ответ

0

DragDrop HowTo

Challange было выяснить, какое свойство должно быть использовано в DragDrop.DoDragDrop(). Поскольку у нас разные ListView, поэтому использование объекта Teacher было бы значимым. Я получаю источник Teacher с левой стороны ListView используя TextBlock.DataContext. И установите его как DataContextDrop targetTextBlock.

Вопрос был, что DataFormats значение для использования DataContext, поэтому я использовал IDataObject.GetFormats().

Выход:

Appointment Schedule Output

Смотрите пример приложения ниже. Вы можете просто скопировать/вставить.

Window1.xaml

<Window x:Class="WpfStackOverflow.MyDragDrop.Window1" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:WpfStackOverflow.MyDragDrop" 
     Title="Window1" Height="472.557" Width="675.564"> 
    <Grid> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="123*"/> 
      <ColumnDefinition Width="380*"/> 
     </Grid.ColumnDefinitions> 

     <ListView Margin="10,31,10,226" ItemsSource="{Binding TeacherData}"> 
      <ListView.Resources> 
       <Style x:Key="TbKey" TargetType="TextBlock"> 
        <EventSetter Event="MouseLeftButtonDown" Handler="Teacher_LeftButtonDown"/> 
        <EventSetter Event="DragEnter" Handler="Teacher_DragEnter"/> 

        <Setter Property="Background" Value="Yellow"/> 
        <Setter Property="AllowDrop" Value="True"/> 
       </Style> 
      </ListView.Resources> 
      <ListView.View> 
       <GridView> 
        <GridView.Columns> 
         <GridViewColumn Header="Teachers" Width="75"> 
          <GridViewColumn.CellTemplate> 
           <DataTemplate> 
            <TextBlock Text="{Binding Name}" Width="{Binding View.Columns[0].Width, RelativeSource={RelativeSource AncestorType=ListView, Mode=FindAncestor}}" 
               Style="{StaticResource TbKey}" /> 
           </DataTemplate> 
          </GridViewColumn.CellTemplate> 
         </GridViewColumn> 
        </GridView.Columns> 
       </GridView> 
      </ListView.View> 
     </ListView> 
     <ListView ItemsSource="{Binding AppointmentData}" Margin="13,31,10,226" Grid.Column="1" ScrollViewer.CanContentScroll="False"> 
      <ListView.Resources> 
       <Style x:Key="TbKey" TargetType="TextBlock"> 
        <EventSetter Event="MouseLeftButtonDown" Handler="WeekDay_LeftButtonDown"/> 
        <EventSetter Event="DragEnter" Handler="WeekDay_DragEnter"/> 
        <EventSetter Event="Drop" Handler="WeekDay_Drop"/> 
        <EventSetter Event="MouseRightButtonDown" Handler="WeekDay_MouseRightButtonDown"/> 

        <Setter Property="Background" Value="Yellow"/> 
        <Setter Property="AllowDrop" Value="True"/> 
        <Setter Property="DataContext" Value="{x:Null}"/> 
        <Style.Triggers> 
         <DataTrigger Binding="{Binding DataContext, RelativeSource={RelativeSource Self}}" Value="{x:Null}"> 
          <Setter Property="Background" Value="{x:Null}"/> 
         </DataTrigger> 
        </Style.Triggers> 
       </Style> 
      </ListView.Resources> 
      <ListView.View> 
       <GridView>      
        <GridView.Columns> 
         <GridViewColumn Header="Workshop" Width="75"> 
          <GridViewColumn.CellTemplate> 
           <DataTemplate> 
            <TextBlock Text="{Binding Workshop}"/> 
           </DataTemplate> 
          </GridViewColumn.CellTemplate> 
         </GridViewColumn> 
         <GridViewColumn x:Name="ColMon" Header="Mon" Width="45"> 
          <GridViewColumn.CellTemplate> 
           <DataTemplate> 
            <TextBlock DataContext="{Binding Mon, Mode=TwoWay}" Text="{Binding Name}" Width="{Binding View.Columns[1].Width, RelativeSource={RelativeSource AncestorType=ListView, Mode=FindAncestor}}" 
               Style="{StaticResource TbKey}" /> 
           </DataTemplate> 
          </GridViewColumn.CellTemplate> 
         </GridViewColumn> 
         <GridViewColumn Header="Tue" Width="45"> 
          <GridViewColumn.CellTemplate> 
           <DataTemplate> 
            <TextBlock DataContext="{Binding Tue, Mode=TwoWay}" Text="{Binding Name}" Width="{Binding View.Columns[1].Width, RelativeSource={RelativeSource AncestorType=ListView, Mode=FindAncestor}}" 
               Style="{StaticResource TbKey}" /> 
           </DataTemplate> 
          </GridViewColumn.CellTemplate> 
         </GridViewColumn> 
         <GridViewColumn Header="Wed" Width="45"> 
          <GridViewColumn.CellTemplate> 
           <DataTemplate> 
            <TextBlock DataContext="{Binding Wed, Mode=TwoWay}" Text="{Binding Name}" Width="{Binding View.Columns[1].Width, RelativeSource={RelativeSource AncestorType=ListView, Mode=FindAncestor}}" 
               Style="{StaticResource TbKey}" /> 
           </DataTemplate> 
          </GridViewColumn.CellTemplate> 
         </GridViewColumn> 
         <GridViewColumn Header="Thu" Width="45"> 
          <GridViewColumn.CellTemplate> 
           <DataTemplate> 
            <TextBlock DataContext="{Binding Thu, Mode=TwoWay}" Text="{Binding Name}" Width="{Binding View.Columns[1].Width, RelativeSource={RelativeSource AncestorType=ListView, Mode=FindAncestor}}" 
               Style="{StaticResource TbKey}" /> 
           </DataTemplate> 
          </GridViewColumn.CellTemplate> 
         </GridViewColumn> 
         <GridViewColumn Header="Fri" Width="45"> 
          <GridViewColumn.CellTemplate> 
           <DataTemplate> 
            <TextBlock DataContext="{Binding Fri, Mode=TwoWay}" Text="{Binding Name}" Width="{Binding View.Columns[1].Width, RelativeSource={RelativeSource AncestorType=ListView, Mode=FindAncestor}}" 
               Style="{StaticResource TbKey}" /> 
           </DataTemplate> 
          </GridViewColumn.CellTemplate> 
         </GridViewColumn> 
        </GridView.Columns> 
       </GridView> 
      </ListView.View> 
     </ListView> 
     <DataGrid IsReadOnly="True" AutoGenerateColumns="False" ItemsSource="{Binding AppointmentData}" Grid.Column="1" HorizontalAlignment="Stretch" Margin="13,243,0,0" VerticalAlignment="Top" > 
      <DataGrid.Columns> 
       <DataGridTextColumn Header="Worskhop" Binding="{Binding Workshop}" Width="*"/> 
       <DataGridTextColumn Header="Mon" Binding="{Binding Mon.Name}" Width="*"/> 
       <DataGridTextColumn Header="Tue" Binding="{Binding Tue.Name}" Width="*"/> 
       <DataGridTextColumn Header="Wed" Binding="{Binding Wed.Name}" Width="*"/> 
       <DataGridTextColumn Header="Thu" Binding="{Binding Thu.Name}" Width="*"/> 
       <DataGridTextColumn Header="Fri" Binding="{Binding Fri.Name}" Width="*"/> 
      </DataGrid.Columns> 
     </DataGrid> 
     <TextBlock Grid.Column="1" HorizontalAlignment="Left" Margin="13,222,0,0" TextWrapping="Wrap" Text="Real time display of workshop schedules" VerticalAlignment="Top" Width="325"/> 
     <TextBlock Grid.Column="1" HorizontalAlignment="Left" Margin="13,10,0,0" TextWrapping="Wrap" Text="Right Click to remove appointment" VerticalAlignment="Top" Width="325"/> 
    </Grid> 
</Window> 

Window1.xaml.cs

using System.Collections.ObjectModel; 
using System.ComponentModel; 
using System.Linq; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Input; 

namespace WpfStackOverflow.MyDragDrop 
{ 
    /// <summary> 
    /// Interaction logic for Window1.xaml 
    /// </summary> 
    public partial class Window1 : Window 
    { 
     ViewModel vm = new ViewModel(); 
     public Window1() 
     { 
      InitializeComponent(); 
      this.DataContext = vm; 
     } 

     #region WeekDay 
      private void WeekDay_DragEnter(object sender, DragEventArgs e) 
      { 
       if (e.Data.GetDataPresent(DataFormats.Text)) 
        e.Effects = DragDropEffects.Copy; 
      } 
      private void WeekDay_Drop(object sender, DragEventArgs e) 
      { 
       ((TextBlock)sender).DataContext = e.Data.GetData(e.Data.GetFormats()[0]); 
      } 
      private void WeekDay_MouseRightButtonDown(object sender, MouseButtonEventArgs e) 
      { 
       (sender as TextBlock).DataContext = null; 
      } 
     #endregion 

     #region Teacher 
      private void Teacher_LeftButtonDown(object sender, MouseButtonEventArgs e) 
      { 
       TextBlock tb = (TextBlock)sender; 
       DragDrop.DoDragDrop(tb, tb.DataContext, DragDropEffects.Copy | DragDropEffects.Move); 
      } 
      private void Teacher_DragEnter(object sender, DragEventArgs e) 
      { 
       if (e.Data.GetDataPresent(DataFormats.Serializable)) 
        e.Effects = DragDropEffects.Copy; 
      } 
     #endregion    
    } 

    public class ViewModel : INotifyPropertyChanged 
    { 
     ObservableCollection<AppointmentRecord> _records = new ObservableCollection<AppointmentRecord>(); 
     public ObservableCollection<AppointmentRecord> AppointmentData { get { return _records; } } 

     ObservableCollection<TeacherRecord> _teacherRecords = new ObservableCollection<TeacherRecord>(); 
     public ObservableCollection<TeacherRecord> TeacherData { get { return _teacherRecords; } } 

     public ViewModel() 
     { 
      TeacherRecord trecord1 = new TeacherRecord() { Name = "A" }; 
      TeacherRecord trecord2 = new TeacherRecord() { Name = "B" }; 
      TeacherRecord trecord3 = new TeacherRecord() { Name = "C" }; 
      TeacherData.Add(trecord1); 
      TeacherData.Add(trecord2); 
      TeacherData.Add(trecord3); 

      AppointmentRecord record1 = new AppointmentRecord() { Workshop = "WS-1", Mon = TeacherData.FirstOrDefault((t) => { return t.Name == "A"; }), Tue = null }; 
      AppointmentRecord record2 = new AppointmentRecord() { Workshop = "WS-2", Mon = null, Tue = TeacherData.FirstOrDefault((t) => { return t.Name == "C"; }) }; 
      AppointmentRecord record3 = new AppointmentRecord() { Workshop = "WS-3", Mon = null, Tue = null, Wed = TeacherData.FirstOrDefault((t) => { return t.Name == "C"; }) };    
      AppointmentData.Add(record1);    
      AppointmentData.Add(record2); 
      AppointmentData.Add(record3); 
     } 

     public event PropertyChangedEventHandler PropertyChanged = delegate { }; 
     public void OnPropertyChanged(string prop) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(prop)); 
     } 
    }  

    public class TeacherRecord 
    { 
     public string Name { get; set; } 
    } 

    public class AppointmentRecord : INotifyPropertyChanged 
    { 
     public event PropertyChangedEventHandler PropertyChanged = delegate { }; 
     public void OnPropertyChanged(string prop) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(prop)); 
     } 

     string _workshop; 
     public string Workshop 
     { 
      get { return _workshop; } 
      set 
      { 
       if (_workshop != value) 
       { 
        _workshop = value; 
        OnPropertyChanged("Workshop"); 
       } 
      } 
     } 

     TeacherRecord _mon; 
     public TeacherRecord Mon 
     { 
      get { return _mon; } 
      set 
      { 
       if (_mon != value) 
       { 
        _mon = value; 
        OnPropertyChanged("Mon"); 
       } 
      } 
     } 

     TeacherRecord _tue; 
     public TeacherRecord Tue 
     { 
      get { return _tue; } 
      set 
      { 
       if (_tue != value) 
       { 
        _tue = value; 
        OnPropertyChanged("Tue"); 
       } 
      } 
     } 

     TeacherRecord _wed; 
     public TeacherRecord Wed 
     { 
      get { return _wed; } 
      set 
      { 
       if (_wed != value) 
       { 
        _wed = value; 
        OnPropertyChanged("Wed"); 
       } 
      } 
     } 

     TeacherRecord _thu; 
     public TeacherRecord Thu 
     { 
      get { return _thu; } 
      set 
      { 
       if (_thu != value) 
       { 
        _thu = value; 
        OnPropertyChanged("Thu"); 
       } 
      } 
     } 

     TeacherRecord _fri; 
     public TeacherRecord Fri 
     { 
      get { return _fri; } 
      set 
      { 
       if (_fri != value) 
       { 
        _fri = value; 
        OnPropertyChanged("Fri"); 
       } 
      } 
     } 
    } 
} 
0

Благодаря AnjumSKhan за отличный ответ! Я внедрил его в свое приложение, и он отлично работает. К сожалению, у меня возникла еще одна проблема.
Поскольку мои данные извлекаются и сохраняются в базе данных, я добавил две переменные:
- INT iTeacherId в классе TeacherRecord (первый столбец с шириной 0 в Listview учителя) и
- INT iWorkShopId к классу AppointmentRecord (первый столбец с шириной 0 в AppointmentData-Listview)
Поэтому, помимо имени учителя, e.Data в WeekDay_Drop теперь также содержит свой идентификатор. Но как мне получить соответствующий идентификатор семинара, чтобы сохранить назначение в Tab_Workshop в базе данных. (Имя и идентификатор учителя находятся в Tab_Teacher, другой таблице базы данных.)

+0

Если ответ решает вашу проблему, отметьте его как правильный ответ. И задавайте отдельные вопросы по отдельным вопросам. Если вы хотите, чтобы я взглянул на ваш вопрос, упомяните меня как @AnjumSKhan в комментарии к вашему вопросу, который уведомит меня. – AnjumSKhan

+0

Извините, теперь я понял! Конечно, класс «AppointmentRecord» предоставляет всю необходимую информацию! – Kenmare

+0

Отметьте свой ответ как правильный ответ, используя небольшую правильную отметку, если мой ответ помог u. – AnjumSKhan