問題
我想在我的應用程式的物件串列中進行更改時重繪 我的 wpf 視圖,但是當我更改值時它不會注冊 INotifyChanged 方法。
我試過
的我去了多個不同的stackoverflow頁面,遇到了同樣的問題,但我沒有讓它正常作業。它不會在串列中的物件中注冊更改。
我的代碼
下面是 WPF 應用程式的 MainWindow 的代碼,其中最后一個按鈕單擊我從串列中更改物件中 XLocation 的值。
public partial class MainWindow : Window
{
private string filePathArtist { get; set; }
private string filePathGrid { get; set; }
public Game.Game Game { get; set; }
public MainWindow()
{
InitializeComponent();
filePathGrid = String.Empty;
filePathArtist = String.Empty;
}
private void BtnOpen_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
bool? res = openFileDialog.ShowDialog();
if (res == true)
{
string filepathgrid = openFileDialog.FileName;
filePathGrid = filepathgrid;
GridTextBox.Text = filepathgrid;
}
}
private void PickArtistBtn_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
bool? res = openFileDialog.ShowDialog();
if (res == true)
{
string filepathartist = openFileDialog.FileName;
filePathArtist = filepathartist;
ArtistTextBox.Text = filepathartist;
}
}
private void CreateGridBtn_Click(object sender, RoutedEventArgs e)
{
Game = new Game.Game(filePathGrid, filePathArtist);
this.DataContext = Game;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Game.Artists[0].XLocation = 30;
}
}
下一個代碼是 Game 類,其中在 Artists 串列中實作了 INotfyPropertyChanged。
public class Game : INotifyPropertyChanged
{
public List<Artist> _artists;
public List<Artist> Artists
{
get
{
return _artists;
}
set
{
_artists = value;
OnPropertyChanged("Artists");
}
}
public List<ITile> Tiles { get; set; }
public Game()
{
}
public Game(string graphPath, string artistPath)
{
IDataParser graphParser = DataFactory.DataFactory.Instance.CreateParser(graphPath);
IDataParser artistParser = DataFactory.DataFactory.Instance.CreateParser(artistPath);
Tiles = graphParser.ParseGridData(graphPath);
Artists = artistParser.ParseArtistData(artistPath);
Test = "new Game";
}
public string Test { get; set; } = "t";
public event PropertyChangedEventHandler? PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
我還在 Artists 類中添加了 INotifyPropertyChanged
public class Artist : INotifyPropertyChanged
{
private float _xLocation;
private float _yLocation;
private int _xVelocity;
private int _yVelocity;
public float XLocation
{
get => _xLocation;
set
{
_xLocation = value;
OnPropertyChanged("XLocation");
}
}
public float ConvertedXLoc
{
get => XLocation * (float)3.75;
set { }
}
public float YLocation
{
get => _yLocation;
set
{
_yLocation = value;
OnPropertyChanged("YLocation");
}
}
public float ConvertedYLoc
{
get => YLocation * (float)3.75;
set { }
}
public int XVelocity
{
get => _xVelocity;
set
{
_xVelocity = value;
}
}
public int YVelocity
{
get => _yVelocity;
set
{
_yVelocity = value;
}
}
public event PropertyChangedEventHandler? PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
然后這里是我將物件系結到 wpf UI 的 Xaml 代碼。
<Window x:Class="BroadwayBoogie.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:game="clr-namespace:BroadwayBoogie.Game"
mc:Ignorable="d"
Title="MainWindow" Height="900" Width="900"
>
<Window.DataContext>
<game:Game/>
</Window.DataContext>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="201*"/>
<ColumnDefinition Width="199*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="21*"/>
<RowDefinition Height="401*"/>
<RowDefinition Height="20*"/>
</Grid.RowDefinitions>
<Button x:Name="BtnOpen" Content="Pick Grid" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Click="BtnOpen_Click"/>
<TextBox x:Name="GridTextBox" HorizontalAlignment="Center" TextWrapping="NoWrap" VerticalAlignment="Center" Width="266" />
<Button x:Name="PickArtistBtn" Content="Pick Artist" HorizontalAlignment="Left" Margin="356,0,0,0" VerticalAlignment="Center" Click="PickArtistBtn_Click" RenderTransformOrigin="-0.135,0.647"/>
<TextBox x:Name="ArtistTextBox" HorizontalAlignment="Left" Margin="30,14,0,0" TextWrapping="NoWrap" VerticalAlignment="Top" Width="231" Grid.Column="1"/>
<Button x:Name="CreateGridBtn" Grid.Column="1" Content="Create Grid" HorizontalAlignment="Left" Margin="311,14,0,0" VerticalAlignment="Top" Click="CreateGridBtn_Click"/>
<Canvas Width="800" Height="800" Grid.ColumnSpan="2" Margin="49,15,51,27" Grid.Row="1" Background="DarkSeaGreen" Grid.RowSpan="2">
<ItemsControl Name="tilesItemsControl" ItemsSource="{Binding Tiles}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Canvas>
<Rectangle
Width="15"
Height="15"
Fill="{Binding Color}"
Canvas.Left ="{Binding ConvertedXLoc}"
Canvas.Top="{Binding ConvertedYLoc}" />
</Canvas>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<ItemsControl Name="ArtistItemsControl" ItemsSource="{Binding Artists}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Canvas>
<Rectangle
Width="3.75"
Height="3.75"
Fill="Black"
Canvas.Left ="{Binding ConvertedXLoc}"
Canvas.Top="{Binding ConvertedYLoc}" />
</Canvas>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Canvas>
<Grid/>
<Button Content="Button" HorizontalAlignment="Left" Margin="4,0,0,0" Grid.Row="2" VerticalAlignment="Center" Click="Button_Click"/>
</Grid>
因此,按下我為測驗目的添加的按鈕。它更改 List 中的值,然后 PropertyChanged 方法應該檢測到它,但它沒有檢測到它只是跳過它。
問題
所以我的基本問題是,我如何檢測藝術家串列中物件的屬性變化。
uj5u.com熱心網友回復:
OnPropertyChanged只有在屬性本身發生更改時才會執行。串列中的新專案不是屬性更改。這就是為什么沒有更新發生的原因。
取而代之的是一個串列,嘗試一個ObservableCollection. AnObservableCollection實作了一個附加功能INotifyCollectionChanged,它使 UI 能夠對串列中更改的專案做出反應。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/513332.html
標籤:C#wpf
