I have a WPF Application with Framework = .NET 6.0
, and I'm using the CommunityToolkit.Mvvm
for my MVVM implementation. I need to create a text box where a user can drag and drop a folder, and in my ViewModel
I need to grab this path. I've tried to implement this using a combination of MVVM
pattern and some code behind in my xaml.cs
, but it's not working quite as expected.
My text box XAML:
<TextBox Grid.Row="0" Grid.Column="1"
Name="TxtPath"
AllowDrop="True"
Drop="TxtPath_Drop"
PreviewDragOver="TxtPath_PreviewDragOver"
Text="{Binding PathText}">
</TextBox>
xaml.cs Code behind:
private void TxtPath_Drop(object sender, DragEventArgs e)
{
var files = (string[])e.Data.GetData(DataFormats.FileDrop);
if (files != null && files.Length != 0)
{
TxtPath.Text = files[0];
}
}
private void TxtPath_PreviewDragOver(object sender, DragEventArgs e)
{
e.Handled = true;
}
My ViewModel:
[ObservableProperty]
private string? pathText;
I expected this to update my PathText
whenever the drag-and-drop operation changes the text, but it doesn't. I get a null
value for PathText
instead. I've confirmed that files[0]
has a valid path value, and that I can visually see the dropped folder path in the text box as well.
Strange thing is, I have a second method in my code behind where a user can click a [ Browse ] button and then select the folder as well, for which I use the method below, and when that's done the PathText
in my ViewModel is updates as expected.
private void BtnBrowse_Click(object sender, RoutedEventArgs e)
{
var folderBrowserDialog = new FolderBrowserDialog();
if (Directory.Exists(TxtPath.Text))
{
folderBrowserDialog.Reset();
folderBrowserDialog.SelectedPath = TxtPath.Text;
}
if (folderBrowserDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
TxtPath.Text = folderBrowserDialog.SelectedPath;
}
}
What am I missing here? Why does the button_Click
event update the bindings but not the textbox_Drop
event?
Edit: typo
CodePudding user response:
The default value of TextBox.Text
's UpdateSourceTrigger is LostFocus and so the binding source will be updated when the TextBox losts focus. See How to: Control When the TextBox Text Updates the Source.
The solution would be to set UpdateSourceTrigger PropertyChanged.
Text="{Binding PathText, UpdateSourceTrigger=PropertyChanged}"
I am not sure what happens in the second case but I guess that sequence somehow changes the focus in your app and triggers the update.