У меня есть ListView отображающий список файлов. При добавлении в ListView предметов, background у добавленного элемента должен быть красным, так как изначально у добавленных файлов MessageFileId == null. Потом для какого либо элемента я меняю MessageFileId на какое либо значение. И когда MessageFileId != null, нужно что бы background у этого элемента стал зеленым. Как такое сделать? На данный момент все элементы имеют только background красного цвета.
ViewModel:
public class TicketAttachFiles
{
public string AttachFilePath { get; set; }
public int? MessageFileId { get; set; }
}
public ObservableCollection<TicketAttachFiles> AttachFiles { get; set; }
Viev:
<ListView Grid.Row="2" Grid.Column="0" Background="Transparent"
ItemsSource="{Binding AttachFiles, UpdateSourceTrigger=PropertyChanged}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem" d:DataContext="{Binding AttachFiles, UpdateSourceTrigger=PropertyChanged}">
<Style.Triggers>
<DataTrigger Binding="{Binding TicketMessageFileId, UpdateSourceTrigger=PropertyChanged}" Value="{x:Null}">
<Setter Property="Background" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<fa:ImageAwesome Icon="PictureOutline" />
<TextBlock Grid.Row="1"
Text="{Binding Path=AttachFilePath}" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
После того как я для какого либо элемента установлю значение поля MessageFileId, у этого элемента не пропадает фон красного цвета.
Вам стоит запомнить одно простое правило.
Если вы меняете значение привязанного свойства из кода и хотите отслеживать это изменение во View слое, то это свойство должно обязательно вызывать INotifyPropertyChanged (INPC)!
То есть вы создаете где то класс, который будет реализовывать INPC.
Самый простой пример:
public class BaseVM : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Далее вы свой класс VM наследуете от ранее созданного класса:
class TicketAttachFiles : BaseVM
И во всех необходимых свойствах вызываете метод оповещения, делая что то вроде:
private int? messageFileId;
public int? MessageFileId
{
get => messageFileId;
set
{
messageFileId = value;
RaisePropertyChanged();
}
}
В данной строке <DataTrigger Binding="{Binding TicketMessageFileId, UpdateSourceTrigger=PropertyChanged}" Value="{x:Null}"> ваша ошибка заключается в том, что свойство TicketMessageFileId будет искаться в главной VM (там, где у вас AttachFiles). Для грамотной работы триггер стоит поместить в DataTemplate самого шаблона.
Разметка будет примерно следующей:
<ListView ItemsSource="{Binding AttachFiles}" >
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock x:Name="TextBlock" Grid.Row="1" Text="{Binding AttachFilePath}"/>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding MessageFileId}" Value="{x:Null}">
<Setter TargetName="TextBlock" Property="TextBlock.Background" Value="Red"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Результат:
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости