WPF ObservableCollection の動作がおかしいです。コレクションが変更され、クラスの一部のプロパティのゲッターメソッドに別の条件がある場合、不明な理由により、View は変更されません。CollectionChanged イベントが呼び出されましたが! ゲッターメソッドのコレクションに条件がなければうまくいきます。
ここで私が自分の仕事のプロジェクトで何をしているかを説明するには、あまりにも複雑で長々としています。したがって、私は小さな単純化プロジェクトを作成し、同じ動作をエミュレートします。このプロジェクトは、何千もの言葉よりも優れた問題を示します。
問題を確認するには、プロジェクトをそのまま起動すると、どのように機能するかがわかります。それは本当にシンプルで、2 つのラジオボタン、データグリッド、そして他には何もありません。次に、MainWindowViewModel、GridItems プロパティに移動し、コメント化されたコードのコメントを解除して、プロジェクトを再度起動します。違いを見ます。コレクションを変更するとき、GridItems-property の get-method は呼び出されません (デバッガーで確認します)。呼び出されたメソッドが何かに影響を与えることはできませんか??? 私はそれについて何の考えも持っていません。助けてください。
プロジェクトのリンク: http://www.megafileupload.com/en/file/443850/ObservableCollection-zip.html
class MainWindowViewModel : ViewModelBase
{
private ObservableCollection<GridItem> _totalStorage;
private ObservableCollection<GridItem> _gridItems;
public ObservableCollection<GridItem> GridItems
{
get
{
//if (_gridItems.Count == 0)
//{
// return _totalStorage;
//}
return _gridItems;
}
set
{
_gridItems = value;
RaisePropertyChanged("GridItems");
}
}
public MainWindowViewModel()
{
_totalStorage = new ObservableCollection<GridItem>();
_gridItems = new ObservableCollection<GridItem>();
GridItemsInit();
_gridItems.CollectionChanged += CollectionChanged;
}
/// <summary>
/// Collection change event handler
/// </summary>
/// <param name="o"></param>
/// <param name="e"></param>
private void CollectionChanged(object o, NotifyCollectionChangedEventArgs e)
{
}
private void GridItemsInit()
{
_totalStorage.Add(new GridItem
{
Name = "Igor",
LastName = "Balachtin",
FilerField = FileStatusEnum.All
});
_totalStorage.Add(new GridItem
{
Name = "Misha",
LastName = "Ivanov",
FilerField = FileStatusEnum.All
});
_totalStorage.Add(new GridItem
{
Name = "Ahmed",
LastName = "Magamed",
FilerField = FileStatusEnum.All
});
_totalStorage.Add(new GridItem
{
Name = "abrek",
LastName = "cheburek",
FilerField = FileStatusEnum.All
});
_totalStorage.Add(new GridItem
{
Name = "Irka",
LastName = "Dirka",
FilerField = FileStatusEnum.All
});
}
private void RefreshGridSource(string statusParam)
{
_gridItems.Clear();
//Если нажали на баттон new
if (statusParam.Equals(FileStatusEnum.All.ToString()))
{
foreach (var item in _totalStorage)
{
_gridItems.Add(item);
}
}
//Если нажали на archived
else if (statusParam.Equals(FileStatusEnum.Filtered.ToString()))
{
foreach (var item in _totalStorage.Where(g => g.FilerField == FileStatusEnum.Filtered))
{
_gridItems.Add(item);
}
}
}
private RelayCommand<object> _radioCommand;
public RelayCommand<object> RadioCommand
{
get { return _radioCommand ?? (_radioCommand = new RelayCommand<object>(HandlerFileRadio)); }
}
private void HandlerFileRadio(object obj)
{
if (obj == null)
return;
var statusParam = obj.ToString();
RefreshGridSource(statusParam);
}
}
Look at this sample.
//if (_gridItems.Count == 0)
//{
// return _totalStorage;
//}
Model:
public enum FileStatusEnum
{
All = 0,
Filtered
}
public class GridItem
{
public String Name { get; set; }
public String LastName { get; set; }
public FileStatusEnum FilerField
{
get; set;
}
}
Xaml:
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="3*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<RadioButton Margin="5" IsChecked="True" Command="{Binding RadioCommand}"
CommandParameter="All">All</RadioButton>
<RadioButton Margin="5" Command="{Binding RadioCommand}"
CommandParameter="Filtered">Filtered</RadioButton>
</StackPanel>
<DataGrid Grid.Column="1" ItemsSource="{Binding GridItems}" CanUserAddRows="False" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Name}" IsReadOnly="True" />
<DataGridTextColumn Header="LastName" Binding="{Binding LastName}" IsReadOnly="True" />
</DataGrid.Columns>
</DataGrid>
</Grid>
リンクの代わりにすべてのコードをここに投稿する方が本当に良いですか? :/