用户控件 UI 没有改变

Usercontrol UI doesn't change

UserControl

  <UserControl x:Class="NolowaFrontend.Views.MainViews.SearchView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:NolowaFrontend.Views.MainViews"
             xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase"
             xmlns:designTime="clr-namespace:NolowaFrontend.Views"
             mc:Ignorable="d" Name="_this"
             d:DesignHeight="300" d:DesignWidth="350" d:Background="White">   
    <Grid>
        <TextBlock Text="{Binding SearchedUsers.Count, diag:PresentationTraceSources.TraceLevel=High}" Foreground="Red" FontSize="20"/>
    </Grid>
</UserControl>

CodeBehind

public partial class SearchView : UserControl
{
    private readonly SearchVM _searchVM;

    public SearchView(User user)
    {
        InitializeComponent();

        _searchVM = new SearchVM(user); ;

        DataContext = _searchVM;
    }

    public void TimerSearch(string text)
    {
        _searchVM.TimerSearch(text);
    }
}

ViewModel

public class SearchVM : ViewModelBase
{
    private readonly User _user;
    private readonly ISearchService _searchService;

    private ObservableCollection<SearchedUser> _searchedUsers = new ObservableCollection<SearchedUser>();

    public ObservableCollection<SearchedUser> SearchedUsers
    {
        get { return _searchedUsers; }
        set { _searchedUsers = value; OnPropertyChanged(); }
    }

    public SearchVM(User user)
    {
        _user = user;
        _searchService = new SearchService();
    }

    public async void TimerSearch(string text)
    {
        var response = await _searchService.SearchUser(text);

        var data = response.ResponseData;

        SearchedUsers = data.ToObservableCollection(); 
    }
}

bindig log

System.Windows.Data Warning: 67 : BindingExpression (hash=11842506): Resolving source 
System.Windows.Data Warning: 70 : BindingExpression (hash=11842506): Found data context element: TextBlock (hash=56511253) (OK)
System.Windows.Data Warning: 78 : BindingExpression (hash=11842506): Activate with root item SearchVM (hash=52539597)
System.Windows.Data Warning: 108 : BindingExpression (hash=11842506):   At level 0 - for SearchVM.SearchedUsers found accessor RuntimePropertyInfo(SearchedUsers)
System.Windows.Data Warning: 104 : BindingExpression (hash=11842506): Replace item at level 0 with SearchVM (hash=52539597), using accessor RuntimePropertyInfo(SearchedUsers)
System.Windows.Data Warning: 101 : BindingExpression (hash=11842506): GetValue at level 0 from SearchVM (hash=52539597) using RuntimePropertyInfo(SearchedUsers): ObservableCollection`1 (hash=49313939 Count=0)
System.Windows.Data Warning: 108 : BindingExpression (hash=11842506):   At level 1 - for ObservableCollection`1.Count found accessor RuntimePropertyInfo(Count)
System.Windows.Data Warning: 104 : BindingExpression (hash=11842506): Replace item at level 1 with ObservableCollection`1 (hash=49313939 Count=0), using accessor RuntimePropertyInfo(Count)
System.Windows.Data Warning: 101 : BindingExpression (hash=11842506): GetValue at level 1 from ObservableCollection`1 (hash=49313939 Count=0) using RuntimePropertyInfo(Count): '0'
System.Windows.Data Warning: 80 : BindingExpression (hash=11842506): TransferValue - got raw value '0'
System.Windows.Data Warning: 84 : BindingExpression (hash=11842506): TransferValue - implicit converter produced '0'
System.Windows.Data Warning: 89 : BindingExpression (hash=11842506): TransferValue - using final value '0'
System.Windows.Data Warning: 56 : Created BindingExpression (hash=29516363) for Binding (hash=55475379) BindingExpression:Path=SearchedUsers.Count; DataItem=null; 
System.Windows.Data Warning: 58 :  Path: 'SearchedUsers.Count'
System.Windows.Data Warning: 60 : BindingExpression (hash=29516363): Default mode resolved to OneWay
System.Windows.Data Warning: 61 : BindingExpression (hash=29516363): Default update trigger resolved to PropertyChanged
System.Windows.Data Warning: 62 : BindingExpression (hash=29516363): Attach to System.Windows.Controls.TextBlock.Text (hash=35990092)
System.Windows.Data Warning: 67 : BindingExpression (hash=29516363): Resolving source 
System.Windows.Data Warning: 70 : BindingExpression (hash=29516363): Found data context element: TextBlock (hash=35990092) (OK)
System.Windows.Data Warning: 71 : BindingExpression (hash=29516363): DataContext is null
System.Windows.Data Warning: 65 : BindingExpression (hash=29516363): Resolve source deferred
System.Windows.Data Warning: 67 : BindingExpression (hash=29516363): Resolving source 
System.Windows.Data Warning: 70 : BindingExpression (hash=29516363): Found data context element: TextBlock (hash=35990092) (OK)
System.Windows.Data Warning: 78 : BindingExpression (hash=29516363): Activate with root item SearchVM (hash=64320678)
System.Windows.Data Warning: 107 : BindingExpression (hash=29516363):   At level 0 using cached accessor for SearchVM.SearchedUsers: RuntimePropertyInfo(SearchedUsers)
System.Windows.Data Warning: 104 : BindingExpression (hash=29516363): Replace item at level 0 with SearchVM (hash=64320678), using accessor RuntimePropertyInfo(SearchedUsers)
System.Windows.Data Warning: 101 : BindingExpression (hash=29516363): GetValue at level 0 from SearchVM (hash=64320678) using RuntimePropertyInfo(SearchedUsers): ObservableCollection`1 (hash=42592467 Count=0)
System.Windows.Data Warning: 107 : BindingExpression (hash=29516363):   At level 1 using cached accessor for ObservableCollection`1.Count: RuntimePropertyInfo(Count)
System.Windows.Data Warning: 104 : BindingExpression (hash=29516363): Replace item at level 1 with ObservableCollection`1 (hash=42592467 Count=0), using accessor RuntimePropertyInfo(Count)
System.Windows.Data Warning: 101 : BindingExpression (hash=29516363): GetValue at level 1 from ObservableCollection`1 (hash=42592467 Count=0) using RuntimePropertyInfo(Count): '0'
System.Windows.Data Warning: 80 : BindingExpression (hash=29516363): TransferValue - got raw value '0'
System.Windows.Data Warning: 84 : BindingExpression (hash=29516363): TransferValue - implicit converter produced '0'
System.Windows.Data Warning: 89 : BindingExpression (hash=29516363): TransferValue - using final value '0'
System.Windows.Data Warning: 95 : BindingExpression (hash=11842506): Got PropertyChanged event from SearchVM (hash=52539597)
System.Windows.Data Warning: 101 : BindingExpression (hash=11842506): GetValue at level 0 from SearchVM (hash=52539597) using RuntimePropertyInfo(SearchedUsers): ObservableCollection`1 (hash=53428882 Count=2)
System.Windows.Data Warning: 105 : BindingExpression (hash=11842506):   Item at level 1 has same type - reuse accessor RuntimePropertyInfo(Count)
System.Windows.Data Warning: 104 : BindingExpression (hash=11842506): Replace item at level 1 with ObservableCollection`1 (hash=53428882 Count=2), using accessor RuntimePropertyInfo(Count)
System.Windows.Data Warning: 101 : BindingExpression (hash=11842506): GetValue at level 1 from ObservableCollection`1 (hash=53428882 Count=2) using RuntimePropertyInfo(Count): '2'
System.Windows.Data Warning: 80 : BindingExpression (hash=11842506): TransferValue - got raw value '2'
System.Windows.Data Warning: 84 : BindingExpression (hash=11842506): TransferValue - implicit converter produced '2'
System.Windows.Data Warning: 89 : BindingExpression (hash=11842506): TransferValue - using final value '2'

嗨!如果有函数调用 SearchView.TimerSearch("x")

我认为 UserControl 显示了从 SearchView.TimerSearch("x")

返回的计数

但它并不像我期望的那样工作。

绑定日志说它更改为 2。但它显示“0”并且从未更改过!

有人可以帮助我吗?

您正在绑定到集合的嵌套 Count 属性。但是由于您要替换整个集合,因此 Count 属性 实际上不会更改,因为 Binding 未检测到集合实例更改。换句话说,Binding 正在侦听 Count 已更改的事件,但此事件从未引发,因为集合实例本身已更改。
通常建议在数据绑定上下文中始终使用相同的集合实例:清除集合并添加新的项目范围。

接下来是您的异步​​方法 TimerSearch:目前未等待并且不会 return Task!
请记住:async void 允许用于事件处理程序。否则,void 方法必须始终转换为 return Task.

当您 await 一个方法时,您必须 await 完整的调用树(所有调用者也是如此):async Task 无处不在。

// Make method return Task
public async Task TimerSearchAsync(string text)
{
    var response = await _searchService.SearchUser(text);

    SearchedUsers.Clear();
    foreach (var data in response.ResponseData)
    {
       SearchedUsers.Add(data);
    }
}

如果 response.ResponseData return 是 List<T>,您可以将 foreach 循环替换为调用 List<T>.ForEach 方法来压缩代码:

response.ResponseData.ForEach(SearchedUsers.Add);

接下来,将调用方法也转换为return一个TaskawaitTimerSearch方法调用:

// Declare method async and return a Task
public async Task TimerSearcAsynch(string text)
{
    await _searchVM.TimerSearchAsync(text);
}

最后,避免在控件中设置 DataContext。这将控件的可用性限制为仅在特殊上下文中使用。

通常,每个控件都没有视图模型 class,这不是您设计控件的方式。控件的开发必须独立于视图模型 class.
在您的情况下,该控件将具有 UserCount 依赖项 属性,您稍后可以将其绑定到外部视图模型。在内部,TextBox 将绑定到 UserCount 依赖项 属性.