2015-09-15 13 views
5

Tôi đã dành hơn nửa ngày cố gắng để làm cho ItemTemplate của một ListView với một UserControl cấu hình thông qua phương tiện của một DependencyProperty trên nói UserControl . Tôi đã gặp một số mâu thuẫn kỳ lạ liên quan đến hai phương thức Binding khác nhau có sẵn trên nền tảng UAP Windows 10 (Bindingx:Bind).ràng buộc vs x: Ràng buộc, sử dụng StaticResource như một mặc định và những khác biệt của họ trong DataContext

UserControl trông giống như thế này và là một phần của thành phần lịch tùy chỉnh.

<UserControl 
    x:Class="FlowDesigner.UserControls.CalendarDayView" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="using:FlowDesigner.UserControls" 
    xmlns:vw="using:FlowDesigner.ViewModels" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:uc="using:FlowDesigner.UserControls" 
    mc:Ignorable="d" 
    d:DesignHeight="300" 
    d:DesignWidth="400" 
    x:Name="DateControl"> 
    <UserControl.Resources> 
     <DataTemplate x:Key="DefaultDataTemplate" x:DataType="vw:Event" > 
      <uc:EventListTemplate IsToday="{Binding Date, Converter={StaticResource IsTodayConverter}}" 
           Date="{Binding Date, Mode=OneWay}" 
           Summary="{Binding Path=Summary, Mode=OneWay}" /> 
     </DataTemplate> 
    </UserControl.Resources> 
    <RelativePanel Background="White" BorderBrush="Black" BorderThickness="1" DataContext="{Binding ElementName=DateControl}"> 
     <TextBlock x:Name="DayText" TextAlignment="Center" VerticalAlignment="Center" /> 
     <TextBlock x:Name="MonthText" TextAlignment="Center" VerticalAlignment="Center" RelativePanel.RightOf="DayText" /> 
     <ListView x:Name="EventList" ItemsSource="{x:Bind Events, Mode=OneWay}" 
       ItemTemplate="{Binding Path=EventItemTemplate, Mode=OneWay, FallbackValue={StaticResource DefaultDataTemplate}, TargetNullValue={StaticResource DefaultDataTemplate}}" 
       RelativePanel.Below="DayText" RelativePanel.AlignLeftWithPanel="True" RelativePanel.AlignRightWithPanel="True"> 

     </ListView> 
    </RelativePanel> 
</UserControl> 

Các EventItemTemplate là một DependencyProperty của UserControl.

public DataTemplate EventItemTemplate 
{ 
    get { return (DataTemplate)GetValue(EventItemTemplateProperty); } 
    set { SetValue(EventItemTemplateProperty, value); } 
} 

public static readonly DependencyProperty EventItemTemplateProperty = 
     DependencyProperty.Register("EventItemTemplate", typeof(DataTemplate), typeof(CalendarDayView), new PropertyMetadata(null)); 

Điều này được thay đổi trên một trong các trang gốc để tạo kiểu ListView theo cách này hay cách khác, như vậy.

<Style TargetType="uc:CalendarDayView"> 
    <Setter Property="EventItemTemplate"> 
     <Setter.Value> 
      <DataTemplate x:DataType="vw:Event" > 
       <TextBlock Text="{Binding Summary, Mode=OneWay}" /> 
      </DataTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

Đây thực sự là phiên bản hoạt động, nhưng tôi đã phải lo lắng với nó một chút. Lần thử đầu tiên được tôi thực hiện với cả hai x:BindBinding và không có DataContext trên RelativePanelUserControl bây giờ. x:Bind sẽ hoạt động khi đặt giá trị thành EventItemTemplate trong trang gốc nhưng không thể sử dụng mặc định DataTemplate được chỉ định bởi StaticResource khi trang gốc không chỉ định bất kỳ điều gì. Binding mặt khác sẽ sử dụng mặc định DataTemplate mọi lúc, ngay cả khi trang gốc đã đặt một giá trị khác thành EventItemTemplate.

Bằng cách đặt DataContext trên RelativePanel thành UserControlBinding cũng bắt đầu hoạt động như mong muốn. x:Bind vẫn hiển thị cùng một hành vi.

Bây giờ tôi hiểu rằng Binding không theo mặc định ràng buộc với UserControl 's DataContext, nhưng tôi vẫn không hoàn toàn chắc chắn lý do tại sao x:Bind không hoạt động. Đây có phải là hành vi dự định hoặc có điều gì đó sai trái với toàn bộ chương trình của tôi ở đây và là những gì tôi nghĩ ra chỉ là một hack may mắn?

Trả lời

8

Từ {x:Bind} markup extension:

Các {x: Bind} đánh dấu mở rộng mới dành cho Windows 10-là một thay thế cho {Binding}. {x: Bind} thiếu một số tính năng của {Binding}, nhưng nó chạy trong thời gian ít hơn và ít bộ nhớ hơn {Binding} và hỗ trợ gỡ lỗi tốt hơn.

Tại thời gian tải XAML, {x: Bind} được chuyển đổi thành những gì bạn có thể nghĩ là đối tượng liên kết và đối tượng này nhận giá trị từ thuộc tính trên nguồn dữ liệu. Đối tượng liên kết có thể được cấu hình tùy ý để quan sát các thay đổi trong giá trị của thuộc tính nguồn dữ liệu và tự làm mới dựa trên những thay đổi đó. Nó cũng có thể được cấu hình tùy chọn để đẩy các thay đổi trong giá trị riêng của nó trở lại thuộc tính nguồn. Các đối tượng liên kết được tạo bởi {x: Bind} và {Binding} phần lớn là tương đương về mặt chức năng. Nhưng {x: Bind} thực thi mã có mục đích đặc biệt, nó tạo ra tại thời gian biên dịch và {Binding} sử dụng kiểm tra đối tượng thời gian chạy chung. Do đó, các ràng buộc {x: Bind} (thường được gọi là các ràng buộc biên dịch) có hiệu suất tuyệt vời, cung cấp xác nhận thời gian biên dịch các biểu thức ràng buộc của bạn và hỗ trợ gỡ lỗi bằng cách cho phép bạn thiết lập các điểm ngắt trong các tệp mã được tạo ra như một phần cho trang của bạn.Các tệp này có thể được tìm thấy trong thư mục obj của bạn, với các tên như (đối với C#) .g.cs.

Các vấn đề liên quan