簡體   English   中英

在單元格上對DataGrid排序后,WPF多個Converter調用

[英]WPF Multiple Converter calls after sorting DataGrid on Cell Click

https://github.com/milanmilas/WPFDataGridSortingColorConverter

我的DataGrid上有一個BackgroundColor轉換器,每個單元調用一次:

Converter Called: Ana , 25
Converter Called: Ana , 25
Converter Called: Dan , 5
Converter Called: Dan , 5
Converter Called: Mike , 65
Converter Called: Mike , 65

DataGrid在每個單元格上具有Click Event,以更新其中一個單元格值(“僅用於測試”)。 Converter每次單元格單擊將觸發3次,但是一旦我通過單擊Name標題對“網格行”進行排序,它將多次觸發,其排序后會像重復的單元格一樣創建:

 Age Incremented
Converter Called: Dan , 10
Converter Called: Dan , 10
Converter Called: Dan , 10
Converter Called: Dan , 10
Converter Called: Dan , 10
Converter Called: Dan , 10
Converter Called: Dan , 10


<Window.Resources>
    <local:SimpleBrushColorConverter x:Key="SimpleColorConverter" />
</Window.Resources>
<Grid>
    <DataGrid ItemsSource="{Binding People}" SelectionUnit="CellOrRowHeader" AutoGenerateColumns="False" CanUserAddRows="False">
        <DataGrid.Columns>
            <DataGridTemplateColumn Header="Name" IsReadOnly="True" SortMemberPath="Age">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Name="Name" Text="{Binding Path=Name, Mode=TwoWay}" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
            <DataGridTemplateColumn Header="Age" IsReadOnly="True">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Name="Age" Text="{Binding Path=Age, Mode=TwoWay}" Background="{Binding Path=Age, Converter={ StaticResource SimpleColorConverter}}" MouseLeftButtonDown="OnCellMouseLeftButtonDown"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>
</Grid>
</Window>


public partial class MainWindow : Window
{
    PeopleViewModel vm = new PeopleViewModel();
    public MainWindow()
    {
        InitializeComponent();

        DataContext = vm;
    }

    private void OnCellMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        Debug.WriteLine("");
        Debug.WriteLine("Age Incremented");
        vm.People.First().Age++;
    }
}

public class SimpleBrushColorConverter : IValueConverter
{
    public object Convert(object values, Type targetType, object parameter, CultureInfo culture)
    {
        Debug.WriteLine("Simple Converter Called: " + values + " , " + values);
        if ((int)values < 18) return new SolidColorBrush(Color.FromRgb(250, 0, 0));
        if (60 > (int)values && (int)values > 18) return new SolidColorBrush(Color.FromRgb(0, 250, 0));
        return new SolidColorBrush(Color.FromRgb(0, 0, 250));
    }

    public object ConvertBack(object value, Type targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

public class PeopleViewModel
{
    public ObservableCollection<Person> People { get; set; }
    public ObservableCollection<Person> People2 { get; set; }

    public PeopleViewModel()
    {
        People = new ObservableCollection<Person>(
            new List<Person>
                {
                    new Person() {Age = 5, Name = "Dan"},
                    new Person() {Age = 25, Name = "Ana"},
                    new Person() {Age = 65, Name = "Mike"}
                }
            );

    }
}

public class NotifyPropertyChanged : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        var handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

public class Person : NotifyPropertyChanged
{
    private string _name;
    private int _age;

    public string Name
    {
        get { return _name; }
        set { _name = value;
        OnPropertyChanged();
        }
    }

    public int Age
    {
        get { return _age; }
        set { _age = value; 
        OnPropertyChanged();
        }
    }
}

如果我使用MultiValueConverter並也綁定到TextBlock,則在排序並單擊單元格后的轉換器中,我可以看到第一個Converter調用是針對具有“ IsVisible = False”的舊值的TextBlock。 第二個調用是針對實際的可見單元格。 再次排序將為舊值之一添加其他帶有“ IsVisible = False”的TextBlock。 這最多可以持續10個TextBlock。 在某些時候,某些TextBlock會被回收,因此它們不再出現在轉換器調用中。

會在轉換器中使用“ IsVisible”來區分有效的TextBlock,但仍不確定為什么會發生這種情況嗎?

public class MultiBrushColorConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        Debug.WriteLine("Simple Converter Called: " + values[0] + " , " + values[0]);
        var textBlock = values[1];
        if ((int)values[0] < 18) return new SolidColorBrush(Color.FromRgb(250, 0, 0));
        if (60 > (int)values[0] && (int)values[0] > 18) return new SolidColorBrush(Color.FromRgb(0, 250, 0));
        return new SolidColorBrush(Color.FromRgb(0, 0, 250));
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

<DataGridTemplateColumn Header="Age" IsReadOnly="True">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Name="Age" Text="{Binding Path=Age}" MouseLeftButtonDown="OnCellMouseLeftButtonDown">
                <TextBlock.Background>
                    <MultiBinding Converter="{StaticResource MultiColorConverter}">
                        <Binding Path="Age" />
                        <Binding RelativeSource="{RelativeSource Self}" />
                    </MultiBinding>
                </TextBlock.Background>
             </TextBlock>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM