gpt4 book ai didi

c# - Wpf 绑定(bind)到对象属性不起作用

转载 作者:太空宇宙 更新时间:2023-11-03 22:43:58 24 4
gpt4 key购买 nike

我有 View 模型

public class MessengerViewModel : INotifyBaseClass
{
public ServiceManager ServiceManager { get; set; }

private ObservableCollection<Conversation> _conversations;
private Conversation _currentConversation;
private MessagesPage _parent;
private List<Conversation> _tempList;
private bool _canClear;
private bool _isSearching;
private Random _random;

public ObservableCollection<Conversation> Conversations
{
get { return _conversations; }
set { SetField(ref _conversations, value); }
}

public Conversation CurrentConversation
{
get { return _currentConversation; }
set
{
_parent.MessagesListBox.ItemsSource = value.Messages;

if (_tempList != null)
{

if (_tempList.Contains(value))
{
_tempList.Remove(value);
}

ClearSearchUsers();
_parent.ConversationsListBox.Items.Refresh();
}

SetField(ref _currentConversation, value);
}
}
...
}

对话准则

public class Conversation : INotifyBaseClass
{
private string _interlocutorId;
private ObservableCollection<Message> _messages;
private string _name;
private string _username;
private Brush _brush;
private bool _isActive;

public bool IsActive
{
get { return _isActive; }
set { SetField(ref _isActive, value); }
}

public string InterlocutorId
{
get { return _interlocutorId; }
set { SetField(ref _interlocutorId, value); }
}

public string Name
{
get { return _name; }
set { SetField(ref _name, value); }
}

public Brush Color
{
get { return _brush; }
set { SetField(ref _brush, value); }
}

public string ShortName
{
get
{
var arr = _name.Split(' ');
if (arr.Length == 1)
return arr[0].ToUpper()[0].ToString();
return arr.Aggregate((x, y) => $"{x[0]}{y[0]}").ToUpper();
}
}

public string Username
{
get { return _username; }
set { SetField(ref _username, value); }
}

public ObservableCollection<Message> Messages
{
get { return _messages; }
set { SetField(ref _messages, value); }
}
}

我的 Xaml 代码:

<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" MinWidth="260"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*" MinWidth="260"/>
</Grid.ColumnDefinitions>
<GridSplitter Grid.Column="1" x:Name="InterfaceSplitter" HorizontalAlignment="Center" Width="3"/>
<Grid Grid.Column="0" x:Name="ConversationsGrid">
<Grid.RowDefinitions>
<RowDefinition Height="65"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Grid x:Name="SearchAndMenuGrid" Grid.Row="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="White">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Source="../Resources/menuIcon.png" Width="40" VerticalAlignment="Center"/>
<TextBox x:Name="SearchTextBox" Grid.Column="1" Height="30" Margin="15" FontFamily="Arial" VerticalContentAlignment="Center" TextChanged="SearchTextBox_TextChanged"/>
</Grid>
<ListBox x:Name="ConversationsListBox" Grid.Row="1" ItemsSource="{Binding Conversations}" SelectedItem="{Binding CurrentConversation}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="White" BorderThickness="0">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="5" Height="55" Orientation="Horizontal" ClipToBounds="True">
<Border Background="{Binding Color}" Width="40" Height="40" VerticalAlignment="Center">
<Border.Clip>
<EllipseGeometry RadiusX="20" RadiusY="20" Center="20,20"/>
</Border.Clip>
<TextBlock FontSize="18" Text="{Binding Path=ShortName}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<TextBlock FontSize="18" Text="{Binding Path=Name}" Margin="15,2.5" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</StackPanel>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsActive}" Value="False">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
<Grid Grid.Column="2" x:Name="MessagesGrid">
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="*"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" x:Name="ConversationPropertiesGrid" Background="White">
<TextBlock Text="{Binding Path = CurrentConversation.Name, Converter={StaticResource DebugDummyConverter}}"/></Grid>
<ListBox x:Name="MessagesListBox" Grid.Row="1" Background="Transparent" HorizontalContentAlignment="Stretch" ItemsSource="{Binding CurrentConversation.Messages}" ItemContainerStyle="{StaticResource RemoveSelectionStyle}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Margin="0,5">
<Border x:Name="MessageBorder" CornerRadius="20">
<TextBlock x:Name="MessageTextBlock" FontSize="18" Text="{Binding Path = Content,PresentationTraceSources.TraceLevel=High}" HorizontalAlignment="Right" Margin="10,15"/>
</Border>
</Grid>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsAuthor}" Value="true">
<Setter TargetName="MessageBorder" Property="Background" Value="White"/>
<Setter TargetName="MessageBorder" Property="HorizontalAlignment" Value="Right"/>
</DataTrigger>
<DataTrigger Binding="{Binding IsAuthor}" Value="false">
<Setter TargetName="MessageBorder" Property="Background" Value="Lime"/>
<Setter TargetName="MessageBorder" Property="HorizontalAlignment" Value="Left"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Grid Grid.Row="2" x:Name="SendMessageGrid" Background="White">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBox Name="MessageTextBox" Grid.Column="0" BorderThickness="0" Margin="10,10" VerticalContentAlignment="Center" AcceptsReturn="True" PreviewKeyDown="MessageTextBox_PreviewKeyDown"/>
</Grid>
</Grid>
</Grid>

问题是当我尝试在 MessageListBox 或 TextBlock {Binding CurrentConversation.Property} 中使用 Binding 时,绑定(bind)失败并显示

System.Windows.Data Warning: 67 : BindingExpression (hash=8769005): Resolving source 
System.Windows.Data Warning: 70 : BindingExpression (hash=8769005): Found data context element: TextBlock (hash=46431654) (OK)
System.Windows.Data Warning: 78 : BindingExpression (hash=8769005): Activate with root item MessengerViewModel (hash=32244734)
System.Windows.Data Warning: 107 : BindingExpression (hash=8769005): At level 0 using cached accessor for MessengerViewModel.CurrentConversation: RuntimePropertyInfo(CurrentConversation)
System.Windows.Data Warning: 104 : BindingExpression (hash=8769005): Replace item at level 0 with MessengerViewModel (hash=32244734), using accessor RuntimePropertyInfo(CurrentConversation)
System.Windows.Data Warning: 101 : BindingExpression (hash=8769005): GetValue at level 0 from MessengerViewModel (hash=32244734) using RuntimePropertyInfo(CurrentConversation): <null>
System.Windows.Data Warning: 106 : BindingExpression (hash=8769005): Item at level 1 is null - no accessor
System.Windows.Data Warning: 80 : BindingExpression (hash=8769005): TransferValue - got raw value {DependencyProperty.UnsetValue}
System.Windows.Data Warning: 88 : BindingExpression (hash=8769005): TransferValue - using fallback/default value ''
System.Windows.Data Warning: 89 : BindingExpression (hash=8769005): TransferValue - using final value ''

但 CurrentConversation 的所有属性都已启动。在开始时,CurrentConversation 为空,直到用户在 ConversationsListBox 中选择它。我想这可能是个问题,但我添加了 _currentConversation = new Conversation() 并且绑定(bind)仍然不起作用。

更新

我的 INotifyBaseClass:

public class INotifyBaseClass : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName]string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

protected bool SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
{
if (EqualityComparer<T>.Default.Equals(field, value))
return false;
field = value;
OnPropertyChanged();
return true;
}
}

最佳答案

在每个 setter 中添加,"" (SetField)

例子:

public bool IsActive
{
get { return _isActive; }
set { SetField(ref _isActive, value, ""); }
}

如果类中有这样一个函数:INotifyBaseClass

protected bool SetField<T>(ref T field, T value, string propertyName)
{
if (EqualityComparer<T>.Default.Equals(field, value)) return false;
field = value;
OnPropertyChanged(propertyName);
return true;
}

关于c# - Wpf 绑定(bind)到对象属性不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50875539/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com