绑定不会更新

时间:2015-11-09 11:52:59

标签: c# wpf mvvm data-binding

我有一个奇怪的问题,我在ListView的DataTemplate中的Textbox不会更新它的数据。数据在我的属性“LastValue”中设置,但它永远不会返回。

这是我的ViewModel代码(仅此类的重要部分):

public interface ISignal : IValue, IChartItem, INotifyPropertyChanged
{
    string SignalName { get; set; }
}

[Serializable]
public class Signal : ObservableObject, ISignal
{
    public Signal()
        : this(new ModelsDialogService())
    {
        LastValue = 0.0;
    }

    public Signal(IDialogService dialog)
    {
        dialogService = dialog;
        VisibleInGraph = true;
        RefreshRate = 1000;
        Include = true;
        Color = ColorList.FirstOrDefault();
        LastValue = 0.0;
    }

    private readonly List<SignalValue> values = new List<SignalValue>();
    [XmlIgnore]
    public IEnumerable<SignalValue> Values
    {
        get
        {
            return values;
        }
    }

    private double lastValue;
    [XmlIgnore]
    public double LastValue
    {
        get
        {
            return lastValue;
        }
        set
        {
            Set(ref lastValue, value);
            //RaisePropertyChanged(() => LastValue);
        }
    }

    public void AddValue(SignalValue val)
    {
        values.Add(val);
        ValueAdded(this, new ValueAddedEventArgs(val));
        LastValue = Convert.ToDouble(((XYValue)val).Value);
    }
}

我的XAML:

<ListView ItemsSource="{Binding SignalGroup.Signals}" SelectedValue="{Binding SelectedSignal}" FontWeight="Normal" BorderThickness="0" Foreground="white" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" DockPanel.Dock="Top" Background="#FF5B5A5A" Margin="10" >
        <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">
                <Style.Resources>
                    <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}"
                         Color="{StaticResource MetroBlueColor}"/>
                </Style.Resources>
                <Setter Property="ContextMenu">
                    <Setter.Value>
                        <ContextMenu ItemsSource="{Binding CommandList}">
                            <ContextMenu.ItemTemplate >
                                <DataTemplate>
                                    <MenuItem Header="{Binding DisplayName}" Command="{Binding ContextMenuCommand}" />
                                </DataTemplate>
                            </ContextMenu.ItemTemplate>
                        </ContextMenu>
                    </Setter.Value>
                </Setter>
                <Setter Property="HorizontalAlignment" Value="Stretch" />
            </Style>
        </ListView.ItemContainerStyle>
        <ListView.ItemTemplate>
            <DataTemplate>
                <DockPanel HorizontalAlignment="Stretch">
                    <TextBlock Text="{Binding SignalName}" DockPanel.Dock="Left" />
                    <TextBlock Text="{Binding LastValue}" TextAlignment="Right" Margin="10,0,10,0" DockPanel.Dock="Right"/>
                </DockPanel>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

感谢您的任何想法。

3 个答案:

答案 0 :(得分:0)

哦,我发现了一个有趣的事实。绑定在反序列化后才起作用。当我创建新的结构等...它工作,但当我使用XMLSerializer将此结构序列化为XML,然后反序列化此类中的每个绑定都不起作用,所以我可以更改所有值,但它没有在GUI中更新...很奇怪< / p>

答案 1 :(得分:0)

我已经实现了一个非常小的MVVM示例。

让我们假设Signal类只有你想要绑定的两个属性。然后Signal看起来很简洁:

public class Signal
{
    public string SignalName { get; set; }

    public double LastValue { get; set; }
}

显然Signal是你的Model

现在您需要在我的小型测试应用程序中具有名称名称的ViewModel

public class ViewModel
{
    public ViewModel()
    {
        this.Signals = new ObservableCollection<Signal>();
        this.Signals.Add(new Signal() { LastValue = 12432.33, SignalName = "First Signal"} );
        this.Signals.Add(new Signal() { LastValue = 2.123, SignalName = "Second Signal"});
    }

    public ObservableCollection<Signal> Signals { get; set; }
}

ObservableCollection就像一个列表,区别在于收集更改时会通知View。该集合会随.Add(...).Remove(...)等操作而变化。

View与您的相似。我选择了一个GridView,因为它更方便,因为它支持排序和编辑元素等功能:

<DataGrid ItemsSource="{Binding Signals}" AutoGenerateColumns="False">
    <DataGrid.Columns>
        <DataGridTextColumn Header="LastName" Binding="{Binding SignalName}" />
        <DataGridTextColumn Header="LastName" Binding="{Binding LastValue}" />
    </DataGrid.Columns>
</DataGrid>

当您使用IsReadOnly时,可能需要将True设置为GridView ListView的解决方案应该看起来一样!

结果:
enter image description here

确保您正确使用MVVM模式。模型仅保存数据。 ViewModel适用于所有业务逻辑,View仅显示数据。

我还建议您创建一个文件夹结构,以便更好地了解您的解决方案。它还使得更容易遵循MVVM模式。

enter image description here

希望它有助于澄清MVVM

答案 2 :(得分:0)

感谢您的要求,这非常有用,但我发现了问题所在。

我的应用程序中有两个集合。我首先添加信号,当用户想要监视其中一些信号时,所选信号也会被推送到第二个集合(但仅限于其参考)。序列化从此结构创建XML,反序列化忽略了引用,并在第一个和第二个集合中创建了一个新的信号对象。现在我们开始! :-D

经过深思熟虑后,我感到非常愚蠢和愚蠢。我必须重构它直到我忘记它。我花了很多时间来查找这个bug的原因。

无论如何,感谢您的要求!