Управление перетаскиванием в деревьях в Winui 3C#

Место общения программистов C#
Ответить
Anonymous
 Управление перетаскиванием в деревьях в Winui 3

Сообщение Anonymous »

Я разрабатываю страницу Winui 3 в C#, где у меня возникают проблемы с настройкой перетаскивания дерева. Проблема заключается в том, что перетаскивание внутри дерева не выполняет метод, определяемый в падении элемента.
Это позволяет вам перемещать все объекты в какую -либо позицию, в то время как для меня элементы, которые используют шаблон: Lavorazionitemplate - это листовые узлы и, следовательно, не могут содержать другие элементы, которые являются тем, что дерево делает, как это есть. />

Код: Выделить всё













































































































< /code>
using CncFileProcessor.Busines;
using CncFileProcessor.Busines.ClassiConcrete;
using CncFileProcessor.Busines.Composite;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Navigation;
using System;
using System.Collections.ObjectModel;
using System.Data.Common;
using System.Diagnostics;
using System.Linq;
using Windows.ApplicationModel.DataTransfer;
using Windows.Storage.Pickers;

// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.

namespace CncFileProcessor.WinUIPack.Finestre
{
/// 
/// An empty page that can be used on its own or navigated to within a Frame.
/// 
public sealed partial class WorkPage : Page
{
public ObservableCollection CncFiles { get; set;  } = new ObservableCollection();

public WorkPage()
{
this.InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);

if (e.Parameter is CncFile cncFile)
{
CncFiles.Add(cncFile);
}
}

private void ItemView_DoubleTapped(object sender, DoubleTappedRoutedEventArgs e)
{
if (Lavori.SelectedItem is CncFile file)
{
WorkPageFrame.Navigate(typeof(FileParamSettingsPage), file);
}
else if (Lavori.SelectedItem is Lavorazione lavorazione)
{
WorkPageFrame.Navigate(typeof(LavorazioneParamSettingsPage), lavorazione);
}
else if (Lavori.SelectedItem is GruppoLavorazioni gruppoLavorazioni)
{
WorkPageFrame.Navigate(typeof(GruppoLavorazioniParamSettings), gruppoLavorazioni);
}
}

private async void New_MenuBar(object sender, RoutedEventArgs e)
{
var dialog = new ContentDialog
{
Title = $"Nuovo Lavoro",
PrimaryButtonText = "Crea",
CloseButtonText = "Cancel",
DefaultButton = ContentDialogButton.Primary,
XamlRoot = this.XamlRoot
};

var textBox = new TextBox
{
PlaceholderText = "Inserisci nome"
};
textBox.MaxLength = 100;
textBox.Width = 500;

dialog.Content = textBox;

//Quando premo il bottone di salvataggio prima di eseguire verifico che sia stato inserito un nome accettabile
dialog.PrimaryButtonClick += (s, e) =>
{
string nome = textBox.Text.Trim();
if (string.IsNullOrWhiteSpace(nome))
{
e.Cancel = true;  // annulla la chiusura
dialog.Title = "Inserire un nome valido";
return;
}

if (AppStateService.GetInstance().CncFiles.Any(f =>
string.Equals(f.Identificatore, nome, StringComparison.OrdinalIgnoreCase)))
{
e.Cancel = true;
dialog.Title = "Il nome esiste già";
return;
}
};

var result = await dialog.ShowAsync();

//salvo le modifiche
if (result == ContentDialogResult.Primary)
{
ICncFileBuilder builder = AppStateService.GetInstance().CncAbstractFactory.CreateFileBuilder();
builder.AddNomeCncFile(textBox.Text);

await using (DbCommand dbCommand = AppStateService.GetInstance().DatabaseAbstractFactory
.CreateCommand(AppStateService.GetInstance().DbConnection,
"insert Lavorazioni (Nome) values (@Nome);SELECT SCOPE_IDENTITY();"))
{
var nomeParam = dbCommand.CreateParameter();
nomeParam.ParameterName = "@Nome";
nomeParam.Value = textBox.Text;
dbCommand.Parameters.Add(nomeParam);

object? resultQuery = await dbCommand.ExecuteScalarAsync();
builder.AddIdCncFile(Convert.ToInt32(resultQuery).ToString());
}
CncFile cncFile = (CncFile)builder.Build();
AppStateService.GetInstance().CncFiles.Add(cncFile);
CncFiles.Add(cncFile);
}
}

private void ItemView_RightTapped(object sender, RightTappedRoutedEventArgs e)
{
// Recupera il ListViewItem da dove è partito il tap destro
var originalSource = e.OriginalSource as FrameworkElement;
if (originalSource != null)
{
// Creazione del menu a comparsa
var menu = new MenuFlyout();

switch (originalSource.DataContext)
{
case CncFile cncFile:
Lavori.SelectedItem = cncFile;

//Creazione sottomenu
var stampaSchedaLavorazione = new MenuFlyoutSubItem { Text = "Stampa Scheda Lavorazione" };
var generaLavorazione = new MenuFlyoutSubItem { Text = "Genera Lavorazione" };

//Creazione item
var aggiungiGruppoLavorazioni = new MenuFlyoutItem { Text = "Aggiungi Gruppo Lavorazioni" };
aggiungiGruppoLavorazioni.Click += (s, args) => AggiungiGruppoLavorazioni(cncFile);

var generaInMacchina = new MenuFlyoutItem { Text = "Macchina" };
generaInMacchina.Click += (s, args) => GeneraLavorazioneInMacchina(cncFile);

var generaInCartella = new MenuFlyoutItem { Text = "Scegli Cartella" };
generaInCartella.Click += (s, args) => GeneraLavorazioneCartella(cncFile);

var stampaSchedaPdfLavorazione = new MenuFlyoutItem { Text = "PDF" };
stampaSchedaPdfLavorazione.Click += (s, args) => StampaSchedaLavorazione(cncFile);

var chiudiCncFile = new MenuFlyoutItem { Text = "Chiudi" };
chiudiCncFile.Click += (s, args) =>  ChiudiCncFile(cncFile);

//Aggiunta item a menu
menu.Items.Add(aggiungiGruppoLavorazioni);
menu.Items.Add(generaLavorazione);
menu.Items.Add(stampaSchedaLavorazione);
menu.Items.Add(chiudiCncFile);

//Aggiunta item a sottomenu
stampaSchedaLavorazione.Items.Add(stampaSchedaPdfLavorazione);
generaLavorazione.Items.Add(generaInMacchina);
generaLavorazione.Items.Add(generaInCartella);

// Mostra il menu sulla posizione cliccata
menu.ShowAt(Lavori, e.GetPosition(Lavori));

break;
case Lavorazione lavorazione:
Lavori.SelectedItem = lavorazione;
var rimuoviLavorazione = new MenuFlyoutItem { Text = "Rimuovi Lavorazione" };
rimuoviLavorazione.Click += (s, args) => RimuoviLavorazione(lavorazione);
menu.Items.Add(rimuoviLavorazione);

menu.ShowAt(Lavori, e.GetPosition (Lavori));

break;
default:
Debug.WriteLine($"Tipo non gestito {originalSource.DataContext}");
break;

}
}
}

private void ChiudiCncFile(CncFile cncFile)
{
//Chiusura semplice ma qui va salvato tutto quello che è modificato
WorkPageFrame.Content = new Page();
CncFiles.Remove(cncFile);
}

private async void AggiungiGruppoLavorazioni(CncFile cncFile)
{
var dialog = new ContentDialog
{
Title = $"Nuovo gruppo lavorazioni",
PrimaryButtonText = "Crea",
CloseButtonText = "Cancel",
DefaultButton = ContentDialogButton.Primary,
XamlRoot = this.XamlRoot
};

var textBox = new TextBox
{
PlaceholderText = "Inserisci nome"
};
textBox.MaxLength = 100;
textBox.Width = 500;

dialog.Content = textBox;

//Quando premo il bottone di salvataggio prima di eseguire verifico che sia stato inserito un nome accettabile
dialog.PrimaryButtonClick += (s, e) =>
{
string nome = textBox.Text.Trim();
if (string.IsNullOrWhiteSpace(nome))
{
e.Cancel = true;  // annulla la chiusura
dialog.Title = "Inserire un nome valido";
return;
}

if (cncFile.Component.Any(f =>
string.Equals(f.Identificatore, nome, StringComparison.OrdinalIgnoreCase)))
{
e.Cancel = true;
dialog.Title = "Il nome esiste già";
return;
}
};

var result = await dialog.ShowAsync();

//salvo le modifiche
if (result == ContentDialogResult.Primary)
{
GruppoLavorazioni gruppoLavorazioni = new GruppoLavorazioni() { Identificatore = textBox.Text };
cncFile.Component.Add(gruppoLavorazioni);
}
}

private async void RimuoviLavorazione(Lavorazione lavorazione)
{

var dialog = new ContentDialog
{
Title = "Conferma",
Content = "Tutte le modifiche andranno perse, sei sicuro?",
PrimaryButtonText = "Sì",
CloseButtonText = "No",
DefaultButton = ContentDialogButton.Primary,
XamlRoot = this.XamlRoot // importante in WinUI 3
};

var result = await dialog.ShowAsync();

if (result == ContentDialogResult.Primary)
{
lavorazione.RefContainer.Component.Remove(lavorazione);
}
}

public void GeneraLavorazioneInMacchina(CncFile cncFile)
{

}

public void GeneraLavorazioneCartella(CncFile cncFile)
{

}

public void StampaSchedaLavorazione(CncFile cncFile)
{

}

private async void CaricaGruppoLavorazioni_MenuBar(object sender, RoutedEventArgs e)
{
CaricaGruppoLavorazioniButton_MenuBar.IsEnabled = false;
// Create a file picker
var openPicker = new Windows.Storage.Pickers.FileOpenPicker();

// See the sample code below for how to make the window accessible from the App class.
var window = App.m_window;

// Retrieve the window handle (HWND) of the current WinUI 3 window.
var hWnd = WinRT.Interop.WindowNative.GetWindowHandle(window);

// Initialize the file picker with the window handle (HWND).
WinRT.Interop.InitializeWithWindow.Initialize(openPicker, hWnd);

// Set options for your file picker
openPicker.ViewMode = PickerViewMode.Thumbnail;
openPicker.FileTypeFilter.Add("*");

// Open the picker for the user to pick a file
var file = await openPicker.PickSingleFileAsync();
if (file != null)
{
ParseResult parseResult =  AppStateService.GetInstance().CncAbstractFactory.CreateParser().Parse(file.Path);
if(parseResult.Success)
{
WorkPageFrame.Navigate(typeof(LavorazioniParsingPage), parseResult.Lavorazioni);
}
else
{
Debug.WriteLine(parseResult.ErrorMessage);
Errore_Tip.IsOpen = true;
}

}
CaricaGruppoLavorazioniButton_MenuBar.IsEnabled = true;
}

private void CaricaSingolaLavorazione_MenuBar(object sender, RoutedEventArgs e)
{

}

private void Lavori_Drop(object sender,  DragEventArgs e)
{
var droppedItems = DragDropService.Instance.TakeDraggedItem();
foreach (UIComponent droppedItem in droppedItems)
{
if (droppedItem is Lavorazione lavorazione)
{
if ((e.OriginalSource as FrameworkElement)?.DataContext is GruppoLavorazioni gruppoLavorazioni)
{
gruppoLavorazioni.Add(lavorazione);
}
else if ((e.OriginalSource as FrameworkElement)?.DataContext is Lavorazione lavorazioneUnder)
{
//Ottengo l'oggetto sopra a cui ho rilasciato il drop
UIComponent component = (UIComponent)(e.OriginalSource as FrameworkElement)?.DataContext;
lavorazioneUnder.RefContainer.Add(lavorazioneUnder.RefContainer.Component.IndexOf(component), lavorazione);
}
}
}
}

private void Lavori_DragOver(object sender, DragEventArgs e)
{
e.Handled = false;
var originalSource = e.OriginalSource as FrameworkElement;
var dragged = DragDropService.Instance.DraggedItem;
var dataContext = originalSource?.DataContext;
if (originalSource?.DataContext is GruppoLavorazioni && dragged.FirstOrDefault() is Lavorazione)
{
e.AcceptedOperation = DataPackageOperation.Move;

// Mostra visivamente che il drop è accettato
e.DragUIOverride.Caption = "Rilascia per inserire lavorazione";
e.DragUIOverride.IsContentVisible = true;
}
else if (originalSource?.DataContext is Lavorazione && dragged.FirstOrDefault() is Lavorazione)
{
e.AcceptedOperation = DataPackageOperation.Move;

// Mostra visivamente che il drop è accettato
e.DragUIOverride.Caption = "Rilascia per inserire lavorazione";
e.DragUIOverride.IsContentVisible = true;
}
else
{
e.AcceptedOperation = DataPackageOperation.None;
}
}

private void ItemView_DragStarting(UIElement sender, DragStartingEventArgs args)
{
if (sender is FrameworkElement element && element.DataContext is UIComponent component)
{
string textDrop = "Utensile " + component.Identificatore;
DragDropService.Instance.ClearDraggedItem();
DragDropService.Instance.AddDraggedItem(component);
args.Data.SetText(textDrop);
args.Data.RequestedOperation = DataPackageOperation.Move;
}
}
}

public class ExplorerItemTemplateSelector : DataTemplateSelector
{
public DataTemplate CncFileTemplate { get; set; }
public DataTemplate GruppiLavorazioneTemplate { get; set; }
public DataTemplate LavorazioniTemplate { get; set; }

protected override DataTemplate SelectTemplateCore(object item)
{
var explorerItem = (UIComponent)item;
if (explorerItem is CncFile)
{
Debug.WriteLine("Selezionato CncFile FolderTemplate");
return CncFileTemplate;
}
else if (explorerItem is GruppoLavorazioni)
{
Debug.WriteLine("Selezionato GruppoLavorazioni FolderTemplate");
return GruppiLavorazioneTemplate;
}
Debug.WriteLine("Selezionato Lavorazione FileTemplate");
return LavorazioniTemplate;
}
}
}
< /code>
и вот классы объектов дерева < /p>
using System.Collections.ObjectModel;
using System.ComponentModel;

namespace CncFileProcessor.Busines.Composite
{
public abstract class UIComponent : INotifyPropertyChanged
{

private string _identificatore;
public ObservableCollection Component { get; } = new ObservableCollection();
public UIComposite RefContainer { get; internal set; }

public string Identificatore
{
get =>  _identificatore;
set
{
if (_identificatore != value)
{
_identificatore = value;
OnPropertyChanged(nameof(Identificatore));
}
}
}

public event PropertyChangedEventHandler? PropertyChanged;
protected void OnPropertyChanged(string propertyName) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

}
}

namespace CncFileProcessor.Busines.Composite
{
public abstract class UIComposite : UIComponent
{
public UIComponent Add(UIComponent component)
{
component.RefContainer = this;
this.Component.Add(component);
return this;
}
public UIComponent Add(int index, UIComponent component)
{
component.RefContainer = this;
this.Component.Insert(index, component);
return this;
}
public UIComponent Remove(UIComponent component)
{
this.Component.Remove(component);
return this;
}

}
}

Классы CNCFILE и Gruppolavorazioni происходят из UIComposite, в то время как класс Lavorazione происходит от UIComponent


Подробнее здесь: https://stackoverflow.com/questions/796 ... in-winui-3
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»