首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C# WPF列表查看项刷新未在OnPropertyChanged之后触发

C# WPF列表查看项刷新未在OnPropertyChanged之后触发
EN

Stack Overflow用户
提问于 2018-12-29 00:38:36
回答 1查看 362关注 0票数 0

我创建了一个视图控件来以图形方式显示数据。由于视图的实例可能很多,所以我使用了一个ListView控件并将其绑定到一个可观察的对象-工作表集合中。sheet是SheetContainer对象的一个可观察集合,它有工作表和名称。观众会显示床单。

列表视图的xaml如下所示:

代码语言:javascript
复制
<ListView x:Name="ListViewSheetSlider" Height="170" Grid.Row="1" BorderThickness="0" 
                              ItemsSource="{Binding Sheets}" SelectionChanged="ListViewSheetSlider_SelectionChanged" >
    <ListView.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Vertical">
                <TextBlock Text="{Binding Name}" />
                <Viewbox Width="150" Height="150">
                    <SheetViewer:Viewer SetSheet="{Binding MySheet, NotifyOnSourceUpdated=True}" />
                </Viewbox>
            </StackPanel>
        </DataTemplate>
    </ListView.ItemTemplate>
    <ListView.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal"></StackPanel>
        </ItemsPanelTemplate>
    </ListView.ItemsPanel>
</ListView>

SelectionChanged方法如下所示:

代码语言:javascript
复制
private void UpdateSheetAndSlider()
{
    workspace.Sheets[SelectedSheetIndex] = MySheetDesigner.Sheet;
    //   ((SheetContainer)ListViewSheetSlider.SelectedItem).MySheet = MySheetDesigner.Sheet;
    Sheets[SelectedSheetIndex].MySheet = MySheetDesigner.Sheet;
}


private void MySheetDesigner_SheetChanged(object sender, EventArgs e)
{
    UpdateSheetAndSlider();
}

private void ListViewSheetSlider_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    int index = ListViewSheetSlider.SelectedIndex;

    UpdateSheetAndSlider();
    SelectedSheetIndex = index;
    MySheetDesigner.Sheet = workspace.Sheets[index];
    ListViewSheetSlider.UpdateLayout();
}

SheetContainer实现很简单。看上去:

代码语言:javascript
复制
public class SheetContainer : INotifyPropertyChanged
{
    public string Name { get; set; }

    private Sheet mySheet;
    public Sheet MySheet
    {
        get => mySheet;
        set
        {
            mySheet = value;

            OnPropertyChanged("MySheet");
        }
    }

    #region INotifyPropertyChanged Handler
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    #endregion

}

查看器xaml和编解码器如下所示:

代码语言:javascript
复制
<UserControl x:Class="SheetViewer.Viewer"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:SheetViewer"
             xmlns:cad="clr-namespace:Cad;assembly=Cad"
             mc:Ignorable="d"        
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid>
        <cad:Cad
            x:Name="CadSurface" >
        </cad:Cad>
    </Grid>
</UserControl>

代码背后:

代码语言:javascript
复制
public partial class Viewer : UserControl
{

    public static readonly DependencyProperty SetSheetProperty =
             DependencyProperty.Register("SetSheet", typeof(Sheet), typeof(Viewer), new
                PropertyMetadata(default(Sheet), new PropertyChangedCallback(OnSetSheetChanged)));

    public Sheet SetSheet
    {
        get { return (Sheet)GetValue(SetSheetProperty); }
        set { SetValue(SetSheetProperty, value);}
    }

    private static void OnSetSheetChanged(DependencyObject d,
       DependencyPropertyChangedEventArgs e)
    {
        Viewer UserControl1Control = d as Viewer;
        UserControl1Control.OnSetSheetChanged(e);
    }

    private void OnSetSheetChanged(DependencyPropertyChangedEventArgs e)
    {
        //tbTest.Text = e.NewValue.ToString();
        Sheet s = (Sheet)e.NewValue;
        DrawSheet(s);
    }

    public Viewer()
    {
        InitializeComponent();
    }


    private void DrawSheet(Sheet sheet)
    {
        CadSurface.Draw();
    }

}

我期望DrawSheet方法在列表视图中的选择更改时触发。更改后的属性会在SheetContainer中触发,但不会进一步传播以绘制工作表。请注意,在填充listview时,将正确调用这些方法并绘制初始视图。

我花了大量的时间,但不知何故我错过了关键的成分。有人能帮忙吗?

谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-12-29 23:32:03

当分配给SetSheet的实例相同时,则不会触发DependencyPropertyChanged事件。这就解释了一切。重点是DependencyProperty在设置值之前检查新旧值是否相等。如果它们相等,则不会传播任何更改。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53965747

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档