Home > Back-end >  Textbox_Drop event doesn't update property in ViewModel
Textbox_Drop event doesn't update property in ViewModel

Time:11-04

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.

  • Related