XAML 在MVVM中正确绑定UserControl的DependencyProperty

ki1q1bka  于 2022-12-07  发布在  其他
关注(0)|答案(1)|浏览(128)

我想创建一个文本框,它可以搜索文件,还可以跟踪以前使用过的文件。因此,我创建了一个带有DependecyProperty的用户控件,它应该提供文本框的当前文本和一个按钮。但是,每次我试图绑定到DependencyProperty时,绑定到它的属性都保持为空。简而言之,该控件如下所示:

<UserControl
    <!-- ... -->
    x:Name="PTB">

    <AutoSuggestBox x:Name="SearchBox"
                    Text="{Binding ElementName=PTB, Path=FilePath, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

    <Button Command="{Binding PickFileCommand}" />
</UserControl

我为用户控件创建了这个简单的ViewModel

public string FilePath
{
     get => _filePath;
     set => SetProperty(ref _filePath, value);
}

public async Task PickFile()
{
     // ...
}

而用户控件的代码隐藏

public readonly static DependencyProperty FilePathProperty =
     DependencyProperty.Register("FilePath", typeof(string), typeof(PathTextBox), new PropertyMetadata("", new PropertyChangedCallback(OnTextChanged)));

public string FilePath
{
     get => (string)GetValue(FilePathProperty);
     set => SetValue(FilePathProperty, value);
}

private static void OnTextChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
     if (dependencyObject is PathTextBox ptb && e.NewValue is string s)
     {
          ptb.SearchBox.Text = s;
          ptb.FilePath = s;
     }
}

当我尝试在MainPage.xaml中这样使用它时:

<customcontrols:PathTextBox x:Name="SearchBox"
                            KeyUp="SearchBox_KeyUp"
                            FilePath="{Binding ScriptFilePath, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>

MainPage.xaml.cs之间的关系

private async void SearchBox_KeyUp(object sender, KeyRoutedEventArgs e)
{
     if (e.Key == VirtualKey.Enter)
     {
          await ViewModel.OpenSqlFile(ViewModel.ScriptFilePath);
     }
}

那么ViewModel.ScriptFilePath仍然是空的,即使我绑定了它。我尝试了几种不同的方法来处理x:Bind等,但是我找不到一种在MVVM中干净地实现它的方法。我使用CommunityToolkit. mvvm库,如果这有帮助的话。有什么想法吗?

zpqajqem

zpqajqem1#

从您的代码中,我假设您在MainPage.xaml.cs中有ViewModel,然后需要将ViewModel添加到绑定代码中。

<customcontrols:PathTextBox
    x:Name="SearchBox"
    KeyUp="SearchBox_KeyUp"
    FilePath="{Binding ViewModel.ScriptFilePath, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>

或者使用x:Bind ViewModel.ScriptFilePath更好。

相关问题