Привязка конвертера значений WPF - что-то не так - PullRequest
3 голосов
/ 08 марта 2011

Представьте, что у вас есть список выбора пользователя. В зависимости от того, какой выбор был сделан пользователем, другие варианты могут быть недоступны.

У меня есть ValueConverter, который потенциально может справиться с этим. Если он знает, какой выбор сделан, он вернет значение, указывающее, можно ли выбрать преобразуемый элемент.

Проблема в том, что единственное место, где можно узнать, какие пользовательские настройки находятся, - это ViewModel для этого экрана. Нет проблем, я все же. Я сделаю конвертер свойством для ViewModel, а в конструкторе для конвертера я передам ссылку на ViewModel, чтобы конвертер мог проверить список выбранных элементов в любое время.

Проблема, с которой я столкнулся сейчас, заключается в том, что она, похоже, фактически не выполняет никаких преобразований.

Чтобы свести это: ViewModel имеет свойство MySelectionConverter типа IValueConverter. ViewModel имеет список выбранных элементов. В представлении (типа MyScreen, который наследуется от UserControl) есть список с элементами.

ItemTemplate выглядит примерно так:

<ListBox.ItemTemplate>
    <DataTemplate>
        <Grid Height="Auto" Width="100" VerticalAlignment="Top"  Visibility="{Binding Path=DataContext.MySelectionConverter, RelativeSource={RelativeSource AncestorType={x:Type MyScreen}}}">
            <TextBlock Text="The user might want to select me." />
        </Grid>
    </DataTemplate>
</ListBox.ItemTemplate>

Я подозреваю, что что-то не так с моим связыванием. Но, может быть, вы просто не можете сделать это вообще. Любая помощь приветствуется.

Edit: На основании информации, которую я получил до сих пор, моя привязка была неверной. Но оказывается, что я не могу сделать то, что пытался сделать. По сути, я пытался установить конвертер через привязку, используя:

Visibility="{Binding Converter={Binding Path=DataContext.StyleOptionConverter, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:StyleSelectionScreen}}}}

Визуальная студия говорит мне:

«Связывание» не может быть установлено на Свойство типа «Конвертер» 'Binding'. «Связывание» может быть установлено только на DependencyProperty DependencyObject.

Итак, теперь я предполагаю, что проблема становится такой: каким образом я могу обойти это? Мне нужен конвертер, который знает о состоянии ViewModel для экрана, на котором он будет использоваться.

Ответы [ 2 ]

3 голосов
/ 08 марта 2011

Ваша привязка неверна. конвертер является свойством привязки, не входящим в свойство Path

Вот пример кода из моего проекта:

<local:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>

и ниже:

<DataGrid ItemsSource="{Binding Path=Tracks, IsAsync=True}" AutoGenerateColumns="False" Height="130" HorizontalAlignment="Left" Name="dataGrid2" 
                                  Visibility="{Binding Path=ShowSongs, Converter={StaticResource BooleanToVisibilityConverter}, Mode=TwoWay}" GridLinesVisibility="Vertical" 
                                  AlternatingRowBackground="{StaticResource Background}">
                            <DataGrid.Columns>
                                <DataGridTextColumn Header="Song" Width="*" Binding="{Binding Name}" />
                                <DataGridTextColumn Header="Artist"  Width="*" Binding="{Binding Artist}" />
                                <DataGridTextColumn Header="Album" Width="*" Binding="{Binding Album}" />
                            </DataGrid.Columns>
                        </DataGrid>

где конвертер - это класс в том же пространстве имен, что и модель представления

public class BooleanToVisibilityConverter : IValueConverter
{

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return (true.Equals(value)) ? Visibility.Visible : Visibility.Hidden;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
2 голосов
/ 08 марта 2011

Оказалось, что мне действительно нужно было MultiBinding и IMultiValueConverter.

XAML выглядит примерно так:

<Grid.Visibility>
    <MultiBinding Converter="{StaticResource styleOptionConverter}">
        <Binding />
        <Binding ElementName="UserControl" Path="DataContext" />
    </MultiBinding>
</Grid.Visibility>

Хотя, по общему признанию, я бы предпочел использовать RelativeSource, а не ElementName, но сейчас этого достаточно, чтобы заставить меня двигаться.

Если кто-нибудь случайно узнает, как работает переплет:

{Binding Path=DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:StyleSelectionScreen}}}

Должно выглядеть, когда написано в MultiBinding, у меня все уши! В противном случае, я думаю, это закрыто.

...