XAML Binding Width of Listview Column

时间:2016-08-30 04:41:38

标签: xaml listview binding uwp

I am loocking to get the same columns width on my two ListViews with binding, currently I found the tool of visual studio: "Create data Binding" and selecting ElementName and my ListView_Original but inside are too many properties and I cant found ColumnDefinition anyway:

enter image description here

I am trying using Width="{Binding Width, ElementName=ListView_FP, Source=Column_Number, Mode=OneWay}" without results but I guess I am near the solution.

What is the correct way to do a binding width of the ColumnDefinition of other Listview.

This is the original listview:

<ListView x:Name="ListView_Original" MaxHeight="400" HorizontalAlignment="Stretch" VerticalAlignment="Top" BorderBrush="Black" BorderThickness="1" Background="WhiteSmoke" SelectionChanged="ListView_Original_SelectionChanged" >
    <ListView.ItemContainerStyle>
        <Style TargetType="ListViewItem">
            <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
        </Style>
    </ListView.ItemContainerStyle>
    <ListView.ItemTemplate>
        <DataTemplate>
            <Grid Padding="0" Margin="0" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*" x:name="Column_Number"/>
                    <ColumnDefinition Width="*" x:name="Column_Name"/>
                    <ColumnDefinition Width="*" x:name="Column_Skill"//>
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="40"/>
                </Grid.RowDefinitions>
                <TextBox Grid.Column="0" TextWrapping="Wrap" BorderBrush="Black" IsReadOnly="True" TextAlignment="Left" IsHitTestVisible="False" x:Name="TextBox_Number" Text="{Binding Path=Number}"/>
                <TextBox Grid.Column="1" TextWrapping="Wrap" BorderBrush="Black" IsReadOnly="True" TextAlignment="Center" IsHitTestVisible="False" x:Name="TextBox_Name" Text="{Binding Path=Name}"/>
                <TextBox Grid.Column="2" TextWrapping="Wrap" BorderBrush="Black" IsReadOnly="True" TextAlignment="Center" IsHitTestVisible="False" x:Name="TextBox_Skill" Text="{Binding Path=Skill}"/>
            </Grid>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

And this is the listview what its columns should do binding:

<ListView x:Name="ListView_Copy" MaxHeight="400" HorizontalAlignment="Stretch" VerticalAlignment="Top" BorderBrush="Black" BorderThickness="1" Background="WhiteSmoke" SelectionChanged="ListView_Copy_SelectionChanged" >
    <ListView.ItemTemplate>
        <DataTemplate>
            <Grid Padding="0" Margin="0" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="{Binding Width, ElementName=ListView_FP, Source=Column_Number, Mode=OneWay}"/>
                    <ColumnDefinition Width="{Binding Width, ElementName=ListView_FP, Source=Column_Name, Mode=OneWay}"/>
                    <ColumnDefinition Width="{Binding Width, ElementName=ListView_FP, Source=Column_Skill, Mode=OneWay}"/>
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="40"/>
                </Grid.RowDefinitions>
                <TextBox Grid.Column="0" TextWrapping="Wrap" BorderBrush="Black" IsReadOnly="True" TextAlignment="Left" IsHitTestVisible="False" x:Name="TextBox_Number" Text="{Binding Path=Number}"/>
                <TextBox Grid.Column="1" TextWrapping="Wrap" BorderBrush="Black" IsReadOnly="True" TextAlignment="Center" IsHitTestVisible="False" x:Name="TextBox_Name" Text="{Binding Path=Name}"/>
                <TextBox Grid.Column="2" TextWrapping="Wrap" BorderBrush="Black" IsReadOnly="True" TextAlignment="Center" IsHitTestVisible="False" x:Name="TextBox_Skill" Text="{Binding Path=Skill}"/>
            </Grid>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Any help is appreciated.

1 个答案:

答案 0 :(得分:1)

x:DataTemplate中使用的Name属性在其外部不可用,因此您必须将ColumnDefinition Width绑定到ListView的DataTemplates可以访问的值。

我已根据您的代码创建了一个示例,该示例能够使用绑定在两个ColumnDefinition中获得相同的动态宽度。

首先,我为ListViews提供了这个共享的DataTemplate:

<Page.Resources>
    <DataTemplate x:Key="SimpleTemplate">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition x:Name="MainDefinition" Width="{Binding ElementName=MainPageName, Path=SameWidth, Converter={StaticResource DoubleToGridLength}, Mode=OneWay}"/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>

            <SymbolIcon Symbol="Accept" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
            <TextBlock Grid.Column="1" Text="{Binding}" VerticalAlignment="Center" FontSize="16"/>
        </Grid>
    </DataTemplate>
</Page.Resources>

然后,我的ListViews:

<ListView Grid.Row="1"
          ItemsSource="{x:Bind ListOneItems}"
          ItemTemplate="{StaticResource SimpleTemplate}"/>
<ListView Grid.Row="1"
          Grid.Column="2"
          ItemsSource="{x:Bind ListTwoItems}"
          ItemTemplate="{StaticResource SimpleTemplate}"/>

Page的代码隐藏:

private double _sameWidth;

public double SameWidth
{
    get { return _sameWidth; }
    set { _sameWidth = value; OnPropertyChanged(); }
}


public ObservableCollection<string> ListOneItems { get; set; }

public ObservableCollection<string> ListTwoItems { get; set; }

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    base.OnNavigatedTo(e);

    var text =
        @"Fugiat laborum cupidatat labore ad dolor officia Lorem ipsum cillum cupidatat dolore enim. Irure aliqua tempor non cupidatat est excepteur nisi labore magna nisi in consequat. Minim ex magna nulla deserunt ad. Proident pariatur deserunt ex voluptate proident irure. Dolore cillum dolor proident eu mollit amet nisi non velit sint.";
    var listOneWords = text.Split(' ').ToList().Take(10);
    var listTwoWords = text.Split(' ').ToList().Skip(10).Take(10);
    ListOneItems = new ObservableCollection<string>(listOneWords);
    ListTwoItems = new ObservableCollection<string>(listTwoWords);
    SameWidth = 48;
}

此外,您需要DoubleToGridLengthConverter:

public class DoubleToGridLengthConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        var width = (double) value;
        var length = new GridLength(width);
        return length;
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new System.NotImplementedException();
    }
}

最后一部分是一个绑定到SameWidth属性的Slider,可动态更改ColumnDefinition Width。

<Slider x:Name="MainSlider" Grid.ColumnSpan="2"
            Minimum="48" 
            Maximum="120" 
            Value="{x:Bind SameWidth, Mode=TwoWay}"/>

希望这能帮到你!