页面代码:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="admin.Views.TableAndDelete"
Title="TableAndDelete">
<ContentPage.Content>
<StackLayout>
<ListView ItemsSource="{Binding IpList}">
<ListView.Header>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Text="IP" FontAttributes="Bold" />
<Label Grid.Column="1" Text="Domain" FontAttributes="Bold" />
<Label Grid.Column="2" Text="IpBroker" FontAttributes="Bold" />
<Label Grid.Column="3" Text="IpStatus" FontAttributes="Bold" />
<Label Grid.Column="4" Text="EnabledTime" FontAttributes="Bold" />
<Label Grid.Column="5" Text="DisabledTime" FontAttributes="Bold" />
<Label Grid.Column="6" Text="DeletedTime" FontAttributes="Bold" />
<Label Grid.Column="7" Text="Action" FontAttributes="Bold" />
<Label Grid.Column="8" Text="Action" FontAttributes="Bold" />
</Grid>
</ListView.Header>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Text="{Binding IP}" />
<Label Grid.Column="1" Text="{Binding Domain}" />
<Label Grid.Column="2" Text="{Binding IpBroker}" />
<!--<Label Grid.Column="3" Text="{Binding IpStatus}" />-->
<Picker Grid.Column="3"
SelectedIndex="{Binding IpStatus, Converter={StaticResource IpStatusConverter}}">
<Picker.ItemsSource>
<x:Array Type="{x:Type x:String}">
<x:String>Unknown</x:String>
<x:String>Enabled</x:String>
<x:String>Disabled</x:String>
<x:String>Deleted</x:String>
</x:Array>
</Picker.ItemsSource>
</Picker>
<Label Grid.Column="4" Text="{Binding ActivedTime}" />
<Label Grid.Column="5" Text="{Binding inActivedTime}" />
<Label Grid.Column="6" Text="{Binding DeletedTime}" />
<!--<Button Grid.Column="1" Text="Delete" Command="{Binding DeleteCommand}" CommandParameter="{Binding Nmae}" />-->
<!--<Button Grid.Column="1" Text="Delete" Command="{Binding DeleteCommand, Source={RelativeSource Self}}" CommandParameter="{Binding .}" />-->
<Button Grid.Column="7" Text="Disable" Clicked="OnDisableButtonClicked"/>
<Button Grid.Column="8" Text="Delete" Clicked="OnDeleteButtonClicked" />
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Button Text="Add IP" Clicked="OnAddButtonClicked"/>
<StackLayout x:Name="dynamicLayout"
HorizontalOptions="Center"/>
</StackLayout>
</ContentPage.Content>
</ContentPage>
后端代码:
using admin.Models;
using System.Collections.ObjectModel;namespace admin.Views;
public partial class TableAndDelete : ContentPage
{
public ObservableCollection<IpInfo> IpList { get; set; }public TableAndDelete()
{
InitializeComponent();
//BindingContext = this;IpList = new ObservableCollection<IpInfo>
{
new IpInfo { IP="127.0.0.1", Domain="test.com", IpBroker="namecheap", IpStatus=IpStatuses.Unknown, ActivedTime=DateTime.Now, DeletedTime=null, inActivedTime=null },
new IpInfo { IP="127.0.0.2", Domain="test.com", IpBroker="namecheap", IpStatus=IpStatuses.Enabled, ActivedTime=DateTime.Now, DeletedTime=null, inActivedTime=null },
new IpInfo {IP = "127.0.0.3", Domain = "test.com", IpBroker = "namecheap", IpStatus = IpStatuses.Disabled, ActivedTime = DateTime.Now, DeletedTime = null, inActivedTime = null},
new IpInfo {IP = "127.0.0.4", Domain = "test.com", IpBroker = "namecheap", IpStatus = IpStatuses.Deleted, ActivedTime = DateTime.Now, DeletedTime = null, inActivedTime = null},
new IpInfo {IP = "127.0.0.5", Domain = "test.com", IpBroker = "namecheap", IpStatus = IpStatuses.Enabled, ActivedTime = DateTime.Now, DeletedTime = null, inActivedTime = null},
};
BindingContext = this; // 绑定必须在加载数据后
}private void OnDeleteButtonClicked(object sender, EventArgs e)
{
var button = (Button)sender;
IpInfo item = button.BindingContext as IpInfo;
if (item != null)
{
string ip = item.IP;
var deletedItem = IpList.Where(s => s.IP == ip).FirstOrDefault();
IpList.Remove(deletedItem);
}
}private void OnAddButtonClicked(object sender, EventArgs e)
{
var inputRow = new StackLayout();
inputRow.Orientation = StackOrientation.Horizontal;
var ipEntry = new Entry();
ipEntry.Placeholder = "IP";
inputRow.Children.Add(ipEntry);var domainEntry = new Entry();
domainEntry.Placeholder = "domain";
inputRow.Children.Add(domainEntry);var ipBrokerEntry = new Entry();
ipBrokerEntry.Placeholder = "Ip Broker";
inputRow.Children.Add(ipBrokerEntry);var addButton = new Button();
addButton.Text = "Add";
addButton.Clicked += (s, ev) =>
{
var ipInfo = new IpInfo
{
IP = ipEntry.Text,
Domain = domainEntry.Text,
IpBroker = ipBrokerEntry.Text,
ActivedTime= DateTime.Now
};IpList.Add(ipInfo);
dynamicLayout.Children.Remove(inputRow);
};
inputRow.Children.Add(addButton);dynamicLayout.Children.Add(inputRow);
}private void OnDisableButtonClicked(object sender, EventArgs e)
{
var button = (Button)sender;
IpInfo item = button.BindingContext as IpInfo;
if (item != null)
{
string ip = item.IP;
var updatedItem = IpList.Where(s => s.IP == ip).FirstOrDefault();
int index = IpList.IndexOf(updatedItem);
//IpList[index].IpStatus = IpStatuses.Disabled;
IpList[index].inActivedTime = DateTime.Now;
}
}
}
我点击Disable button,通过后端改了数据,但是前端不变。
根据您提供的代码,我发现在OnDisableButtonClicked方法中,您更新了IpList中的数据,但没有通知UI进行刷新。这可能导致前端不同步的问题。为了解决这个问题,您可以将ObservableCollection<IpInfo>更改为BindableObjectCollection<IpInfo>,它是一个可绑定的集合类型,当集合中的数据发生变化时,会自动通知UI进行更新。
首先,您需要在XAML文件中引入xmlns:local="clr-namespace:admin.Views",并将ListView的ItemsSource更改为BindableObjectCollection<IpInfo>:
xml
Copy code
<ListView ItemsSource="{Binding IpList}" x:DataType="local:TableAndDelete.BindableObjectCollection`1[admin.Models.IpInfo]">
然后,创建一个名为BindableObjectCollection的类,继承自ObservableCollection<T>,并实现INotifyPropertyChanged接口。这个类将处理数据更新后通知UI刷新的逻辑:
csharp
Copy code
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
namespace admin.Views
{
public class BindableObjectCollection<T> : ObservableCollection<T>
{
public new event PropertyChangedEventHandler PropertyChanged;
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
base.OnCollectionChanged(e);
OnPropertyChanged(new PropertyChangedEventArgs("Count"));
OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
}
protected override void OnPropertyChanged(PropertyChangedEventArgs e)
{
base.OnPropertyChanged(e);
PropertyChanged?.Invoke(this, e);
}
}
}
接下来,在TableAndDelete类中,将IpList的类型更改为BindableObjectCollection<IpInfo>:
csharp
Copy code
public BindableObjectCollection<IpInfo> IpList { get; set; }
并在构造函数中实例化BindableObjectCollection<IpInfo>:
csharp
Copy code
IpList = new BindableObjectCollection<IpInfo>
{
// ...
};
现在,当您在后端更新IpList中的数据时,UI会自动收到通知并进行更新,解决了前后端数据不同步的问题。
<ListView ItemsSource="{Binding IpList}" x:DataType="local:TableAndDelete.BindableObjectCollection`1[admin.Models.IpInfo]">
这一句报错:not found