【问题标题】:WPF Listview ModelView only update onceWPF Listview ModelView 只更新一次
【发布时间】:2020-03-10 18:02:16
【问题描述】:

我想从 ModelView 更新 ListView,它只能工作一次(在程序启动时),这是错误的。 BatterieApiMqtt_MessageReceived 方法每两秒调用一次,值在变化。

谢谢

这是我的代码

型号

    public class AccuModel : INotifyPropertyChanged
{

    private string id;
    private string voltage;
    private string current;
    private string power;
    private string ladezustand;
    private string restkapazität;

    [JsonProperty("id")]
    public string Id
    {
        get { return id; }
        set
        {
            id = value;
            OnPropertyChanged("Id");
        }
    }

    [JsonProperty("voltage")]
    public string Voltage
    {
        get { return voltage; }
        set
        {
            voltage = value;
            OnPropertyChanged("Voltage");
        }
    }

    [JsonProperty("current")]
    public string Current
    {
        get { return current; }
        set
        {
            current = value;
            OnPropertyChanged("Current");
        }
    }

    [JsonProperty("power")]
    public string Power
    {
        get { return power; }
        set
        {
            power = value;
            OnPropertyChanged("Power");
        }
    }

    [JsonProperty("ladezustand")]
    public string Ladezustand
    {
        get { return ladezustand; }
        set
        {
            ladezustand = value;
            OnPropertyChanged("Ladezustand");
        }
    }

    [JsonProperty("restkapazität")]
    public string Restkapazität
    {
        get { return restkapazität; }
        set
        {
            restkapazität = value;
            OnPropertyChanged("Restkapazität");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

}

型号 公开课 EnergieMonitor { [JsonProperty("值")] 公共 IList accuValues { 获取;放; } }

模型视图

public class AccuViewModel 
{
    private IList<AccuModel> _AccuModelsList;
    private Api.BatterieApi BatterieApiMqtt;
    public AccuViewModel()
    {
        this.BatterieApiMqtt = new Api.BatterieApi();
        BatterieApiMqtt.MessageReceived += BatterieApiMqtt_MessageReceived; 
    }

    private void BatterieApiMqtt_MessageReceived(object sender, EventArgs e)
    {
        var values = BatterieApiMqtt.EnergieMonitorValues().accuValues;
        _AccuModelsList = new List<AccuModel>();

        if (_AccuModelsList.Count > 0)
        {
            _AccuModelsList.Clear();
        }

        for (int i = 0; i < values.Count; i++)
        {
            _AccuModelsList.Add(new AccuModel());
            _AccuModelsList[i] = values[i];
        }
    }

    public IList<AccuModel> AccuModel
    {
        get { return _AccuModelsList; }
        set { _AccuModelsList = value; }
    }
}

Control.cs

 public ucWBatterie12VUebersicht()
    {
        InitializeComponent();
        AccuViewModel viewModel = new AccuViewModel();
        ListAccus.DataContext = viewModel;
    }

Control.xaml

<Grid Margin="10,90,1170,320">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <ListView Name="ListAccus" Grid.Row="1" Margin="10,10,0,10"  ItemsSource="{Binding AccuModel}" FontSize="18"  FontFamily="Arial" Foreground="WhiteSmoke" Background="Transparent" AlternationCount="2" ItemContainerStyle="{StaticResource alternateColor}">
            <ListView.View>
                <GridView>
                    <GridView.ColumnHeaderContainerStyle>
                        <Style TargetType="{x:Type GridViewColumnHeader}">
                            <Setter Property="Background" Value="#FF5B8577"/>
                            <Setter Property="Height" Value="30"/>
                        </Style>
                    </GridView.ColumnHeaderContainerStyle>
                    <GridViewColumn Header="ID" DisplayMemberBinding="{Binding Id}"  Width="50"/>
                    <GridViewColumn Header="Spannung [V]" DisplayMemberBinding="{Binding Voltage, Mode=TwoWay}"  Width="120" />
                    <GridViewColumn Header="Strom [A]" DisplayMemberBinding="{Binding Current, Mode=TwoWay}" Width="120" />
                    <GridViewColumn Header="Leistung [W]" DisplayMemberBinding="{Binding Power, Mode=TwoWay}" Width="120" />
                    <GridViewColumn Header="Ladezustand [%]" DisplayMemberBinding="{Binding Ladezustand, Mode=TwoWay}" Width="150" />
                    <GridViewColumn Header="Restkapazität [Ah]" DisplayMemberBinding="{Binding Ladezustand, Mode=TwoWay}" Width="150" />
                </GridView>
            </ListView.View>
        </ListView>
    </Grid>

【问题讨论】:

  • 尝试使用ObservableCollection&lt;AccuModel&gt; 而不是List。另外,在添加另一个项目之前不要清除列表,只需添加它。
  • 您的意思是在 AccuViewModel.cs 中?同一件事只更新一次
  • 如果您更新支持字段 (_AccuModelsList) 而不是属性 (AccuModelsList),propertychanged 事件不会触发,UI 不会更新。并且不要忘记将 Inotifypropertychanged 添加到您的 Viewmodel 中!您绑定不会触发任何事件的 Viewmodel

标签: wpf data-binding


【解决方案1】:
  1. 在您的 Viewmodel 上实现 InotifyPropertychanged 接口
  2. 用户 ObservableCollection 而不是 IList(正如 slugster 建议的那样)
  3. 更新您的属性 (AccumodelList) 而不是支持字段 (_AccuModelList)

这应该可以解决您的问题。

您可能会考虑不清除列表,只需分配新值(可能会提高性能...)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-24
    • 2022-10-20
    相关资源
    最近更新 更多