简体   繁体   中英

Binding wont update

I have strange problem, my Textbox in ListView's DataTemplate wont update its data. Data are setted in my property "LastValue" but it was never return.

Here is my ViewModel code (only important parts of this class):

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);
    }
}

And my 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>

Thanks for any idea.

Oh, i found interesting fact. Binding doesn't work only after deserialization. When I create new structure etc.. it works but when I serialize this structure to XML using XMLSerializer and then deserialize every binding in this class doesen't work, so I can change all values but its not updated in GUI... Weird

I have implemented a very small MVVM example.

Lets assume that the Signal class has only the two attributes you want to bind to. Then Signal looks very clean and easy:

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

    public double LastValue { get; set; }
}

Obviously Signal is your Model !

Now you need the ViewModel which has the name name in my small test application:

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; }
}

An ObservableCollection is like a list with the difference that the View is notified when the Collection changes. The collection changes with operations like .Add(...) and .Remove(...) .

The View looks similar to yours. i have choosen a GridView, because it is much more handy because it supports features like sorting and editing of the elements:

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

You may want to set the IsReadOnly to True when you are using the GridView A solution with a ListView should look the same!

The Result:
在此处输入图片说明

Make sure, that you use the MVVM Pattern correctly. The Model only holds the data. The ViewModel is for all the business logic and the View only shows the data.

I would also recommend to create a folder structure so you have better overview over your solution. It also makes it easier to follow the MVVM pattern.

在此处输入图片说明

Hope it helps and clarified MVVM

Thank you for your request, it is really useful, but I´ve found where the problem is.

I have two collections in my application. I add Signals to first and when user wants to monitor some of these signals, selected signals are putted to the second collection too(but only its reference). Serialization creates the XML from this structure and deserialization overlooks the references and creates a new object of signal in first and also second collection. And here we go! :-D

I feel really stupid and dumb after dicovering this. I must refactor it till I forgot it. I spent a lot of time by searching the cause of this bug.

Thank for your request anyway!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM