2012-11-01 30 views
5

पर अतिरिक्त पंक्तियों की प्रतिलिपि बनाएँ मैं WPF डेटाग्रिड के साथ काम कर रहा हूं और मैं प्रतिलिपि & पेस्ट तंत्र को बढ़ाने/बदलने की कोशिश कर रहा हूं।डब्ल्यूपीएफ डाटाग्रिड:

जब उपयोगकर्ता कुछ कक्षों का चयन करता है और फिर CTRL + C दबाता है, अंतर्निहित नियंत्रण CopyingRowClipboardContent ईवेंट को पकड़ने में सक्षम है।

this.mainDataGrid.CopyingRowClipboardContent 
       += this.DatagridOnCopyingRowClipboardContent; 

इस विधि में, कुछ कक्ष शीर्षलेख और पंक्तियों दोनों में जोड़े जाते हैं, जिसके परिणामस्वरूप "व्यापक" ग्रिड होता है।

private void DatagridOnCopyingRowClipboardContent(
     object sender, 
     DataGridRowClipboardEventArgs dataGridRowClipboardEventArgs) 
    { 
     // this is fired every time a row is copied 
     var allContent = dataGridRowClipboardEventArgs.ClipboardRowContent; 

     allContent.Insert(0, new DataGridClipboardCellContent(
              null, 
              this.mainDataGrid.Columns[0], 
              "new cell")); 
    } 

इस बिंदु मैं अटक कर रहा हूँ क्योंकि मैं अंतिम पंक्ति के बाद शीर्षक और दो से पहले एक अतिरिक्त पंक्ति जोड़ने के लिए कोशिश कर रहा हूँ पर (नीचे छवि देखें)।

कोई विचार? सुझाव?

कृपया ध्यान दें कि मुझे यहां ऐसा करने के एमवीवीएम तरीके से रूचि नहीं है।

enter image description here

+0

मीठा पिक आप इसे कैसे आकर्षित किया? –

+2

धन्यवाद।पुरानी स्कूल कलम और कागज ==> आईफोन तस्वीर ==> फेंट और पेंट.Net के साथ समायोजित करें। पूरे शायद एक मिनट से भी कम समय लेता है। तथ्य यह है कि मैं अपने दाहिने हाथ का उपयोग आकस्मिक है। :) – mhttk

उत्तर

3

कोड स्निपेट जो आपकी मदद कर सकता है। यह स्निपेट मुख्य रूप से हेडर समेत आपके सभी चुने गए डेटा को पुनर्प्राप्त करने के लिए उपयोग किया जाता है (मैंने RowHeaders भाग हटा दिया है क्योंकि आपको स्पष्ट रूप से इसकी आवश्यकता नहीं है)। यदि आपके कोई प्रश्न हैं तो कृपया मुझे बताएं। मैंने पूंजी अक्षरों में लिखी टिप्पणियों के साथ कुछ हिस्सा छोड़ा: यह वह जगह है जहां आपको अपना डेटा जोड़ना चाहिए इस दृष्टिकोण का अच्छा हिस्सा यह है कि यह सीधे आपके DataGrid के ItemsSource के साथ काम करता है और DataGridCell नहीं। मुख्य कारण यह है कि: यदि आप उदाहरण के लिए स्वरूपित संख्या पर DataGridCell का उपयोग करते हैं, तो आपको वास्तविक मान नहीं मिलेगा, लेकिन केवल स्वरूपित एक (आपका स्रोत 14.4 9 है और आपका StringFormat एन 0 है, तो आप केवल 14 की प्रतिलिपि बनायेंगे यदि आप उपयोग करते हैं एक "नियमित" तरीका)

/// <summary> 
    /// Handles DataGrid copying with headers 
    /// </summary> 
    /// <param name="sender"></param> 
    /// <param name="e"></param> 
    private void OnCopyingDataGrid(object sender, ExecutedRoutedEventArgs e) 
    { 
     // First step: getting the coordinates list of all cells selected 
     IList<Tuple<int, int>> cellsCoordinatesList = new List<Tuple<int, int>>(); 
     HashSet<int> rowList = new HashSet<int>(); 
     HashSet<int> columnList = new HashSet<int>(); 
     foreach (System.Windows.Controls.DataGridCellInfo cell in this.SelectedCells) 
     { 
      int column = cell.Column.DisplayIndex; 
      int row = this.Items.IndexOf(cell.Item); 
      cellsCoordinatesList.Add(new Tuple<int, int>(row, column)); 
      if (!rowList.Contains(row)) 
      { 
       rowList.Add(row); 
      } 
      if (!columnList.Contains(column)) 
      { 
       columnList.Add(column); 
      } 
     } 

     // Second step: Create the table to copy/paste 
     object[,] arrayToBeCopied = new object[rowList.Count, columnList.Count + 1]; 
     IList<string> colHead = this.ColumnHeaders.Cast<object>().Select(h => h.ToString()).ToList(); 
     for (int row = 0; row < arrayToBeCopied.GetLength(0); row++) 
     { 
      for (int column = 0; column < arrayToBeCopied.GetLength(1); column++) 
      { 
       if (row == 0) 
       { 
        arrayToBeCopied[row, column] = colHead[columnList.ElementAt(column - 1)]; 
       } 
       else 
       { 
        arrayToBeCopied[row, column] = // WHATEVER YOU WANT TO PUT IN THE CLIPBOARD SHOULD BE HERE. THIS SHOULD GET SOME PROPERTY IN YOUR ITEMSSOURCE 

       } 
      } 
     } 

     // Third step: Converting it into a string 
     StringBuilder sb = new StringBuilder(); 

     // HERE, ADD YOUR FIRST ROW BEFORE STARTING TO PARSE THE COPIED DATA 

     for (int row = 0; row < arrayToBeCopied.GetLength(0); row++) 
     { 
      for (int column = 0; column < arrayToBeCopied.GetLength(1); column++) 
      { 
       sb.Append(arrayToBeCopied[row, column]); 
       if (column < arrayToBeCopied.GetLength(1) - 1) 
       { 
        sb.Append("\t"); 
       } 
      } 
      sb.Append("\r\n"); 
     } 

     // AND HERE, ADD YOUR LAST ROWS BEFORE SETTING THE DATA TO CLIPBOARD 

     DataObject data = new DataObject(); 
     data.SetData(DataFormats.Text, sb.ToString()); 

     Clipboard.SetDataObject(data); 
    } 
+0

यह काफी दिलचस्प है। तो आपका दृष्टिकोण वास्तव में पूरी तरह से ग्रिड के भीतर तंत्र को बाईपास करना है। – mhttk

+0

बिल्कुल, मैंने प्रतिलिपि/पेस्ट व्यवहार को फिर से परिभाषित किया क्योंकि जैसा कि मैंने उपरोक्त समझाया है, डिफ़ॉल्ट व्यक्ति मेरी आवश्यकताओं को पूरा नहीं करता है (जिसे मैं प्राकृतिक मानता हूं, मूल्यों की प्रतिलिपि बनाता हूं और स्क्रीन पर जो लिखा गया है उसे नहीं): / – Damascus

0

क्या आप सामग्री को प्रतिलिपि बनाने की कोशिश कर रहे हैं एक्सेल बाद में? हां, तो यहाँ मैं क्या किया बताया गया है:

/// <summary> 
/// Copy the data from the data grid to the clipboard 
/// </summary> 
private void copyDataOfMyDataGridToClipboard(object sender, EventArgs e) 
{ 
    // Save selection 
    int selectedRow = this.myDataGrid.SelectedRows[0].Index; 

    // Select data which you would like to copy 
    this.myDataGrid.MultiSelect = true; 
    this.myDataGrid.SelectAll(); 

    // Prepare data to be copied (that's the interesting part!) 
    DataObject myGridDataObject = this.myDataGrid.GetClipboardContent(); 
    string firstRow = "FirstRowCommentCell1\t"+ this.someDataInCell2 +"..\r\n"; 
    string lastTwoRows = "\r\nBottomLine1\t" + yourvariables + "\r\nBottomLine2"; 
    string concatenatedData = firstRow + myGridDataObject.GetText() + lastTwoRows; 

    // Copy into clipboard 
    Clipboard.SetDataObject(concatenatedData); 

    // Restore settings 
    this.myDataGrid.ClearSelection(); 
    this.myDataGrid.MultiSelect = false; 

    // Restore selection 
    this.myDataGrid.Rows[selectedRow].Selected = true; 
} 

मेरे मामले में मैं था कुछ स्थिर हेडर की जो आसानी से कुछ चर के साथ concatenated जा सकता है। लिखने के लिए महत्वपूर्ण \t एक और सेल घोषित करने के लिए \r\n अगली पंक्ति

0

मुझे यह एक पुरानी पोस्ट का एहसास है, लेकिन मैं इस समाधान को पूर्णता के लिए पोस्ट करता हूं। मुझे क्लिपबोर्ड पर डेटाग्रिड पंक्तियों की प्रतिलिपि बनाने पर एक और हालिया प्रश्न नहीं मिला। क्लिपबोर्ड का उपयोग करना .etData ClipboardRowContent इरादे को बेकार करता है।

मेरी ज़रूरतों के लिए, मैं वापस पंक्ति में चिपक रहा हूं। मैं जिस पंक्ति को चाहूंगा। सेल। यह सभी जानकारी है जो मुझे प्रत्येक चयनित पंक्ति के लिए चाहिए।

संकेत: मुझे e.clipboardRowContent.Clear() के बिना डुप्लिकेट मिल रहा था; e.ClipboardRowContent का उपयोग करने के बाद। मैं पहले और डेटाग्रिड का उपयोग कर साफ़ कर रहा था। पंक्तियों का निर्माण करने के लिए चयन किया गया।

private void yourDataGrid_CopyingRowClipboardContent(object sender, DataGridRowClipboardEventArgs e) 
{ 
var dataGridClipboardCellContent = new List<DataGridClipboardCellContent>(); 

string prevCell = ""; 
string curCell = ""; 

foreach (DataGridClipboardCellContent cell in e.ClipboardRowContent) 
{ 
    //Gives you access item.Item or item.Content here 
    //if you are using your struct (data type) you can recast it here curItem = (yourdatatype)item.Item;   
    curItem = cell.Item.ToString(); 

    if (curCell != prevCell) 
     dataGridClipboardCellContent.Add(new DataGridClipboardCellContent(item, item.Column, curCell)); 

    prevCell = curCell; 

} 
e.ClipboardRowContent.Clear(); 

//Re-paste back into e.ClipboardRowContent, additionally if you have modified/formatted rows to your liking 
e.ClipboardRowContent.AddRange(dataGridClipboardCellContent); 

}

संबंधित मुद्दे