Обновление привязки, использующей конвертер значений - PullRequest
3 голосов
/ 18 марта 2010

У меня есть пользовательский интерфейс WPF, связанный с объектом. Я использую ValueConverter для преобразования свойства в определенное изображение по бизнес-правилу:


    public class ProposalStateImageConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var proposal = value as Proposal;
            var basePath = "pack://application:,,,/ePub.Content;component/Images/General/Flag_{0}.png";
            string imagePath;

            if(proposal.Invoice != null)
            {
                imagePath = string.Format(basePath, "Good");
            }
            else
            {
                imagePath = string.Format(basePath, "Warning");
            }

            var uri = new Uri(imagePath);
            var src = uri.GetImageSource(); //Extention method

            return src;
        }
    }

Элемент представляет собой TreeView, где изображение находится на 2-м уровне:


    <TreeView x:Name="tree"
              ItemsSource="{Binding People}" 
              SelectedItemChanged="OnTreeItemChanged">
        <TreeView.Resources>
            <HierarchicalDataTemplate DataType="{x:Type dmn:Person}" 
                                      ItemsSource="{Binding Proposals}">
                <StackPanel Orientation="Horizontal" ToolTip="{Binding Path=Fullname}" Margin="3">
                    <Image Margin="5,0,5,0" Width="16" Height="16" Source="pack://application:,,,/ePub.Content;component/Images/General/Person_Active.png" />
                    <TextBlock Text="{Binding Path=Firstname}" />
                    <TextBlock Text="{Binding Path=Lastname}" Margin="5,0,0,0" />
                </StackPanel>
            </HierarchicalDataTemplate>
            <HierarchicalDataTemplate DataType="{x:Type dmn:Proposal}">
                <StackPanel Orientation="Horizontal" Margin="3">
                    <b><Image x:Name="invoiceImage" Width="16" Height="16" Margin="5,0,5,0" Source="{Binding, Converter={StaticResource ProposalStateImageConverter}, UpdateSourceTrigger=PropertyChanged}" /></b>
                    <TextBlock Text="{Binding DeliveryDate, Converter={StaticResource textCulturedDateConverter}}" />
                </StackPanel>
            </HierarchicalDataTemplate>
        </TreeView.Resources>
    </TreeView>

Работает нормально, но позже, когда состояние объекта меняется, я хочу обновить изображение и пересчитать преобразователь значений. Как это возможно?

Ответы [ 2 ]

3 голосов
/ 18 марта 2010

Похоже, что вы используете только одно значение внутри преобразователя и просто делаете переключение между двумя значениями, чтобы вместо этого вы могли просто сделать это прямо в XAML с помощью триггера. Этот метод также переключается на привязку к свойству Invoice, чтобы любые уведомления об изменениях для этого свойства приводили к обновлению триггера.

<HierarchicalDataTemplate >
    <StackPanel Orientation="Horizontal" Margin="3">
        <Image x:Name="invoiceImage" Width="16" Height="16" Margin="5,0,5,0" Source="good.png"/>
        <TextBlock ... />
    </StackPanel>
    <HierarchicalDataTemplate.Triggers>
        <DataTrigger Binding="{Binding Invoice}" Value="{x:Null}">
            <Setter TargetName="invoiceImage" Property="Source" Value="warning.png"/>
        </DataTrigger>
    </HierarchicalDataTemplate.Triggers>
</HierarchicalDataTemplate>
3 голосов
/ 18 марта 2010

Предполагая, что вы не можете использовать INotifyPropertyChanged, поскольку привязываете весь объект, вам нужно вызвать BindingExpression.UpdateTarget .

Небольшая тонкость заключается в том, чтобы овладеть выражением связывания. Это требует от вас достаточно глубоких знаний о представлении: насколько я знаю, единственный способ сделать это - вызвать BindingOperations.GetBindingExpression , передав элемент управления и свойство, привязку которого вы хотите обновить, например:

BindingOperations.GetBindingExpression(myImage, Image.SourceProperty).UpdateTarget();
...