2013-03-12 46 views
7

Về cơ bản tôi đã ràng buộc datagrid để nó giống như một thời gian biểu của các đối tượng - mỗi hàng đại diện cho một học kỳ của các môn học, và mỗi ô trong học kỳ đó đại diện cho một chủ đề.Làm cách nào để truy cập đối tượng dữ liệu của một DataGridCell trong mã?

Tôi hiện đang cố gắng thêm chức năng kéo và thả để bạn có thể kéo các đối tượng khác vào lưới và điều này sẽ cập nhật cơ sở hạ tầng cơ bản.

Tôi có thể sử dụng một số phương pháp cây trực quan để tìm DataGridCell mà người dùng đang kéo chủ đề mới, nhưng tôi không biết cách truy cập giá trị (chủ đề) mà ô được gắn với nó để thay thế giá trị trống/giữ chỗ bằng chủ đề mới. Có cách nào để truy cập vào giá trị cơ bản hay tôi nên cơ cấu lại toàn bộ phương pháp tạo chương trình này?

An example of the grid and the subjects to be dragged onto it

+0

bạn có thể dán cấu trúc lưới không? – Freelancer

+0

GridView thực hoặc cấu trúc cơ bản? – Miguel

+0

chỉ cần cột và dữ liệu exaple – Freelancer

Trả lời

3

Để có được dữ liệu của DataGridCell, bạn có thể sử dụng nó DataContext và Column tài sản. Cách thực hiện điều đó chính xác tùy thuộc vào dữ liệu hàng của bạn, tức là những gì bạn đặt trong bộ sưu tập ItemsSource của DataGrid. Giả sử các mặt hàng của bạn đang object[] mảng:

// Assuming this is an array of objects, object[],this gets you the 
// row data as you have them in the DataGrid's ItemsSource collection 
var rowData = (object[]) DataGrid.SelectedCells[0].Item; 
// This gets you the single cell object 
var celldata = rowData[DataGrid.SelectedCells[0].Column.DisplayIndex]; 

Nếu dữ liệu hàng của bạn là phức tạp hơn, bạn cần phải viết một phương pháp theo đó dịch các Column bất động sản và các mục dữ liệu hàng với giá trị cụ thể về mục dữ liệu hàng của bạn.


EDIT:

Nếu ô bạn thả dữ liệu của bạn vào không phải là ô đã chọn, một lựa chọn là để có được những DataGridRowDataGridCell thuộc, sử dụng VisualTreeHelper:

var parent = VisualTreeHelper.GetParent(gridCell); 
while(parent != null && parent.GetType() != typeof(DataGridRow)) 
{ 
    parent = VisualTreeHelper.GetParent(parent); 
} 
var dataRow = parent; 

Sau đó, bạn có hàng và có thể tiến hành như trên.


Bên cạnh đó, liên quan đến câu hỏi của bạn cho dù bạn nên xem xét lại phương pháp này, tôi sẽ đề nghị sử dụng tùy chỉnh WPF hành vi s.

Hành vi cung cấp một cách chuyển tiếp rất nhanh để mở rộng khả năng của điều khiển từ mã C#, thay vì XAML, nhưng vẫn giữ mã số của bạn rõ ràng và đơn giản (không chỉ tuyệt vời nếu bạn theo dõi MVVM). Hành vi được thiết kế theo cách mà chúng có thể tái sử dụng và không bị ràng buộc với sự kiểm soát cụ thể của bạn.

Here's a good introduction

Đối với trường hợp đặc biệt của bạn, tôi chỉ có thể cung cấp cho bạn một ý tưởng về những việc cần làm:

Viết một DropBehavior cho sự kiểm soát TextBlock của bạn (hoặc bất kỳ điều khiển bạn muốn bên DataGridCells của bạn, mà xử lý thả. ý tưởng cơ bản là để đăng ký tùy theo hành động với EVNT của các tế bào trong phương pháp OnAttached() tầm kiểm soát của bạn.

public class DropBehavior : Behavior<TextBlock> 
{ 
    protected override void OnAttached() 
    { 
     AssociatedObject.MouseUp += AssociatedObject_MouseUp; 
    } 

    private void AssociatedObject_MouseUp(object sender, MouseButtonEventArgs e) 
    { 
     // Handle what happens on mouse up 

     // Check requirements, has data been dragged, etc. 
     // Get underlying data, now simply as the DataContext of the AssociatedObject 
     var cellData = AssociatedObject.DataContext; 

    } 
} 

Lưu ý rằng, phân tích các dữ liệu của các tế bào đơn lẻ fro m dữ liệu hàng và thuộc tính Column trở nên lỗi thời.

Sau đó, bạn đính kèm hành vi này để TextBlocks, mà bạn đặt bên trong các tế bào của bạn, bằng cách sử dụng ContentTemplate của CellStyle của DataGrid của bạn:

<DataGrid> 
    <DataGrid.CellStyle> 
     <Style TargetType="DataGridCell"> 
      <Setter Property="ContentTemplate"> 
       <Setter.Value> 
        <DataTemplate> 
         <TextBlock Text="{Binding}"> 
          <i:Interaction.Behaviors> 
           <yourns:DropBehavior/> 
          </i:Interaction.Behaviors> 
         </TextBlock> 
        </DataTemplate> 
       </Setter.Value> 

      </Setter> 
     </Style> 
    </DataGrid.CellStyle> 
</DataGrid> 

Bạn có thể tìm Behavior<T> baseclass trong

Hệ thống .Windows.Interactivity.dll

Tôi chưa thử nghiệm, nhưng tôi hy vọng nó phù hợp với bạn và bạn có ý tưởng ...

+0

Tôi sẽ xem xét điều WPF Behaviors, nhờ liên kết. Tuy nhiên đối với phần đầu tiên của câu trả lời của bạn tôi không thể làm một trong hai giải pháp của bạn. Trong ví dụ đầu tiên bạn sử dụng DataGrid.SelectedCells [0] trả về một DataGridCellInfo mà tôi * không có *. Hãy nhớ rằng tôi chỉ có DataGridCell mà tôi nhận được từ vị trí chuột sau khi kéo thả, tôi không có lựa chọn. Tôi có thể chọn ô này và sau đó làm phương pháp này nhưng tôi không muốn thay đổi lựa chọn của người dùng. – Miguel

+0

Trong phương pháp thứ hai, bạn sử dụng rowData [Column Index]. Tôi có thể lấy chỉ mục cột vì tôi có cột (đó là thuộc tính của DataGridCell), nhưng tôi không biết hàng hiện tại của ô để có cấu trúc rowData đúng. – Miguel

+0

@Miguel: Tôi đã trích dẫn bài đăng của mình. Tôi chắc chắn sẽ khuyên bạn nên sử dụng hành vi. Nó thực sự không phải là phức tạp và imho tất cả điều này tìm kiếm hàng cha mẹ và đúc xung quanh không phải là phong cách tốt cũng không hiệu quả. – Marc

Các vấn đề liên quan