Как получить связанные ListboxItems из ListView в WPF - PullRequest
1 голос
/ 22 февраля 2010

Я довольно новичок в WPF, так что извините за любой тупой вопрос ...

У меня есть ListView с тремя столбцами, который связан с источником XmlDataProvider, как показано ниже:

        <XmlDataProvider x:Key="Properties" XPath="/Info">
        <x:XData>
            <Info xmlns="">
                <Property Name="Text" Value=""/>                <!--0-->
                <Property Name="Tooltip" Value=""/>             <!--1-->
                <Property Name="Enable" Value=""/>              <!--2-->
                <Property Name="Visible" Value=""/>             <!--3-->
                <Property Name="Focus" Value=""/>               <!--4-->
                <Property Name="Selected" Value=""/>            <!--5-->
                <Property Name="Count" Value=""/>               <!--6-->
                <Property Name="Item" Value=""/>                <!--7-->
                <Property Name="SelectedText" Value=""/>        <!--8-->
                <Property Name="SelectedIndex" Value=""/>       <!--9-->
                <Property Name="Complete" Value=""/>            <!--10-->
            </Info>
        </x:XData>
    </XmlDataProvider>

ListView определяется следующим образом:

        <ListView Name="lstProperties"  Margin="55 0 0 0" Style="{DynamicResource TsListView}"
        Grid.Row="2" Grid.RowSpan="7" Grid.ColumnSpan="4"
        ItemsSource="{Binding Source={StaticResource Properties}, XPath=Property}" 
        ItemContainerStyle="{DynamicResource TsListViewItem}" 
        ScrollViewer.HorizontalScrollBarVisibility="Hidden"
        SelectionMode="Single" IsEnabled="False"
        SelectionChanged="propertySelected" 
        >

        <ListView.View>
            <GridView AllowsColumnReorder="False">
                <GridViewColumn CellTemplate="{StaticResource FirstCell}" Width="25" />
                <GridViewColumn Header="Property" Width="80">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <Label Style="{DynamicResource TsLabel}" Height="25" Width="115" Content="{Binding XPath=@Name}" />
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                <GridViewColumn Header="Value" Width="130">
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <TextBox Style="{DynamicResource TsHelperTextBox}"
                                     Height="20" Width="115" Text="{Binding XPath=@Value}" 
                                     IsEnabled="{Binding ElementName=rbTypeAssert, Path=IsChecked}" GotFocus="gridTextBox_GotFocus" />
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>
            </GridView>
        </ListView.View>
    </ListView>

То, что я хочу сделать сейчас, довольно просто: я просто хочу включить / отключить некоторые из ListViewItems. Единственный способ получить ListViewItems - это следующий метод:

lstProperties.ItemContainerGenerator.ContainerFromIndex(index)

Это заставляет меня чувствовать себя немного неловко. Я должен получать Предметы через свойство name объекта Property. Есть какой-либо способ сделать это? У меня также возникают проблемы, когда я пытаюсь сделать это сразу после инициализации окна. Я получаю исключение NullReferenceException при попытке отключить один из этих ListViewItems. Кажется, что сразу после рендеринга окна привязка еще не завершена.

Ответы [ 3 ]

1 голос
/ 24 февраля 2010

Kents ответ правильный, но я бы использовал конвертер вместо расширения вашей модели:

<ListView>
    <ListView.ItemContainerStyle>
        <Style TargetType="ListViewItem">
            <Setter Property="IsEnabled" Value="{Binding Converter={StaticResource IsEnabledConverter}}"/>
        </Style>
    </ListView.ItemContainerStyle>
</ListView>

И конвертер:

public class IsEnabledConverter : IValueConverter
{
    #region IValueConverter Members

    public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        //Implement your logic here, and return true/false accordingly
        return true;
    }

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

    #endregion
}
1 голос
/ 22 февраля 2010

Самый простой и лучший способ сделать это - выставить свойство, которое определяет, должен ли ListViewItem быть включен или нет, а затем привязаться к нему:

<ListView>
    <ListView.ItemContainerStyle>
        <Style TargetType="ListViewItem">
            <Setter Property="IsEnabled" Value="{Binding YourProperty}"/>
        </Style>
    </ListView.ItemContainerStyle>
</ListView>
0 голосов
/ 24 февраля 2010

Что ж, ваш отзыв в сочетании с другими полученными отзывами позволил мне решить проблему. Большое спасибо!

Я добавил новый атрибут IsEnable к свойству в XmlDataProvider, а затем я связал свойство IsEnabled объекта ListViewItem с этим новым атрибутом. Поэтому вместо того, чтобы иметь одно глобальное свойство для определения состояния всех элементов ListViewItems, как вы предложили, у меня будут «отдельные привязки».

Для программного изменения данных я использовал следующий метод:

provider.Document.SelectSingleNode("//Property[Name=\"Text\"]/IsEnable").InnerText = false.ToString();

Этот метод требует немного другой формат данных. Таким образом, XmlDataProvider теперь выглядит следующим образом:

        <XmlDataProvider x:Key="Properties" XPath="/Info" IsAsynchronous="False" IsInitialLoadEnabled="True">
        <x:XData>
            <Info xmlns="">
                <Property>
                    <Name>Text</Name>
                    <Value></Value>
                    <IsEnable>true</IsEnable>
                </Property>
                <Property>
                    <Name>Tooltip</Name>
                    <Value></Value>
                    <IsEnable>true</IsEnable>
                </Property>
                <Property>
                    <Name>Enable</Name>
                    <Value></Value>
                    <IsEnable>true</IsEnable>
                </Property>
                <Property>
                    <Name>Visible</Name>
                    <Value></Value>
                    <IsEnable>true</IsEnable>
                </Property>
                <Property>
                    <Name>Focus</Name>
                    <Value></Value>
                    <IsEnable>true</IsEnable>
                </Property>
                <Property>
                    <Name>Selected</Name>
                    <Value></Value>
                    <IsEnable>true</IsEnable>
                </Property>
                <Property>
                    <Name>Count</Name>
                    <Value></Value>
                    <IsEnable>true</IsEnable>
                </Property>
                <Property>
                    <Name>Item</Name>
                    <Value></Value>
                    <IsEnable>true</IsEnable>
                </Property>
                <Property>
                    <Name>SelectedText</Name>
                    <Value></Value>
                    <IsEnable>true</IsEnable>
                </Property>
                <Property>
                    <Name>SelectedIndex</Name>
                    <Value></Value>
                    <IsEnable>true</IsEnable>
                </Property>
                <Property>
                    <Name>Complete</Name>
                    <Value></Value>
                    <IsEnable>true</IsEnable>
                </Property>
            </Info>
        </x:XData>
    </XmlDataProvider>

Еще раз спасибо за ваш вклад! Хосе Таварес

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...