5

リスト ボックスにバインドされたObservableCollectionと、ボタンにバインドされたブールプロパティがあります。次に、 2 つのコンバーターを定義しました。1 つはコレクションを操作し、もう 1 つはブール プロパティを操作します。ブール値のプロパティを変更するたびに、コンバーターのConvertメソッドが呼び出されますが、監視可能なコレクションを変更しても同じメソッドは呼び出されません。私は何が欠けていますか??

参考までにスニペット、

xaml スニペット、

<Window.Resources>
    <local:WrapPanelWidthConverter x:Key="WrapPanelWidthConverter" />
    <local:StateToColorConverter x:Key="StateToColorConverter" />
</Window.Resources>
<StackPanel>
    <ListBox x:Name="NamesListBox" ItemsSource="{Binding Path=Names}">
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel x:Name="ItemWrapPanel" Width="500" Background="Gray">
                    <WrapPanel.RenderTransform>
                        <TranslateTransform x:Name="WrapPanelTranslatation" X="0" />
                    </WrapPanel.RenderTransform>
                    <WrapPanel.Triggers>
                        <EventTrigger RoutedEvent="WrapPanel.Loaded">
                            <BeginStoryboard>
                                <Storyboard>
                                    <DoubleAnimation Storyboard.TargetName="WrapPanelTranslatation" Storyboard.TargetProperty="X" To="{Binding Path=Names,Converter={StaticResource WrapPanelWidthConverter}}" From="525"  Duration="0:0:2" RepeatBehavior="100" />
                                </Storyboard>
                            </BeginStoryboard>
                        </EventTrigger>
                    </WrapPanel.Triggers>
                </WrapPanel>
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <Label Content="{Binding}" Width="50" Background="LightGray" />
                </Grid>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    <Button Content="{Binding Path=State}" Background="{Binding Path=State, Converter={StaticResource StateToColorConverter}}" Width="100" Height="100" Click="Button_Click" />
</StackPanel>   

コード ビハインド スニペット

public class WrapPanelWidthConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        ObservableCollection<string> aNames = value as ObservableCollection<string>;
        return -(aNames.Count * 50);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}


public class StateToColorConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        bool aState = (bool)value;
        if (aState)
            return Brushes.Green;
        else
            return Brushes.Red;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}   
4

3 に答える 3

17

マルチバインディングコンバータを使用して、この問題を解決できます。Collection.Countその後、プロパティとコレクションに同時にバインドできます。カウントによりバインディングがトリガーされて再評価され、2番目のバインディングを使用して必要に応じて値を実際に変換します

<TextBlock IsHitTestVisible="false"
    Margin="5,0"
    TextTrimming="CharacterEllipsis"
    VerticalAlignment="Center"
    DockPanel.Dock="Left" >
    <TextBlock.Text>
        <MultiBinding Converter="{Resources:ListToStringConverter}">
            <Binding Path="List.Count" />
            <Binding Path="List" />
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>
于 2012-06-04T15:36:30.170 に答える
13

ソースが更新され、その更新について(または を使用して)通知Bindingされる場合、 a のコンバーターは常に呼び出されると思います。ただし、アイテムが追加または削除された場合、はイベントを発生させませんが、イベントを発生させます。コレクション内のアイテムが変更された場合、イベントはまったく発生しません。アイテム自体が を発生させても、ソースはアイテムではなくコレクションであるため、これはコレクションの を更新しません。BindingDependencyPropertyINotifyPropertyChangedObservableCollectionPropertyChangedCollectionChangedPropertyChangedBindingBinding

あなたのアプローチがこのように機能しないのではないかと心配しています。直接バインドしてObservableCollection.Count適切な数学コンバーターを追加して反転と乗算を実行できますが、Countプロパティは変更通知を実行しないため、このオプションはありません。これらのケースを処理するViewModelまたはコードビハインドで別のプロパティを提供する必要があると思います...

于 2010-05-12T06:57:23.733 に答える
2

バインディングが発生したとき、またはプロパティが変更されたときに、コンバーターが呼び出されます。したがって、ブール値が変更されるたびに、コンバーターがブール値に対して呼び出されます。コレクションは一度設定され、それがバインディングが発生してコンバーターが使用されるときです。コレクションの内部が変更された場合(コレクションが追加または削除された場合)、プロパティは変更されないため(つまり、新しいコレクションをバインドしていない場合)、コンバーターは再度起動しません。

ビューモデルを使用してコレクションをラップし、変更通知を実装するcountなどの別のプロパティを追加します。ここからこのラッパークラスを使用して、コレクションをラップし、そこにプロパティを簡単に追加できます。

于 2010-05-12T07:09:42.627 に答える