C# 从Windows应用商店应用中的ItemTemplate中绑定父DataContext
在项目模板中绑定项目模板父上下文时遇到问题 有很多“变通方法”只在WPF中有效(即使用C# 从Windows应用商店应用中的ItemTemplate中绑定父DataContext,c#,mvvm,windows-store-apps,winrt-xaml,attached-properties,C#,Mvvm,Windows Store Apps,Winrt Xaml,Attached Properties,在项目模板中绑定项目模板父上下文时遇到问题 有很多“变通方法”只在WPF中有效(即使用FindAncestor和AncestorType)。这是毫无疑问的,因为它在Windows应用商店应用程序中不受支持 其他解决方案建议使用ElementName。虽然这适用于Windows应用商店应用程序,但这不是一个可接受的解决方案,因为它不可能重复使用数据模板 我读过的一个解决方案是使用附加属性/附加行为,这听起来像是一种非常通用和可重用的方法。但到目前为止我还没能成功 我当前的尝试是,创建一个全局附加属
FindAncestor
和AncestorType
)。这是毫无疑问的,因为它在Windows应用商店应用程序中不受支持
其他解决方案建议使用ElementName
。虽然这适用于Windows应用商店应用程序,但这不是一个可接受的解决方案,因为它不可能重复使用数据模板
我读过的一个解决方案是使用附加属性/附加行为,这听起来像是一种非常通用和可重用的方法。但到目前为止我还没能成功
我当前的尝试是,创建一个全局附加属性并在ItemTemplate
中访问它
public class GlobalProperties : DependencyObject
{
public static object GetParentDataContext(DependencyObject obj)
{
return (object)obj.GetValue(ParentDataContextProperty);
}
public static void SetParentDataContext(DependencyObject obj, object value)
{
obj.SetValue(ParentDataContextProperty, value);
}
// Using a DependencyProperty as the backing store for ParentDataContext. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ParentDataContextProperty =
DependencyProperty.RegisterAttached("ParentDataContext",
typeof(object),
typeof(GlobalProperties),
new PropertyMetadata(null, ParentDataContextChanged));
private static void ParentDataContextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
SetParentDataContext(d, e.NewValue);
}
}
和我的XAML(通过在ListViews XAML代码中内联DataTemplate而简化。它稍后将存储在DataTemplate.XAML文件的外部
<ListView
my:GlobalProperties.ParentDataContext="{Binding}"
ItemsSource="{Binding Questions}"
>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
<Setter Property="Margin" Value="0,-1,0,0" />
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid Background="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(my:GlobalProperties.ParentDataContext).Site.Styling.TagBackgroundColor}">
<!-- Item Related DataBindings -->
</Grid>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
参考上面的评论,我将给出示例代码 Main.xaml
<Page
x:Class="TempApp.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:converter="using:TempApp"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ListView x:Name="MyList">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
<Setter Property="Margin" Value="0,-1,0,0" />
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<Grid x:Name="ListItemDataTemplateGrid"
HorizontalAlignment="Stretch">
<Grid.Resources>
<converter:ValueToBackgroundConverter x:Key="ValueToBackgroundConverter" BackgroundColor="{Binding BgColor}" />
</Grid.Resources>
<Grid Background="{Binding Converter={StaticResource ValueToBackgroundConverter}}">
<!--Your Content-->
</Grid>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
我认为,在这种情况下,使用dependency属性创建转换器会起作用。听起来是一种有趣的方法,但不确定它将如何工作。dependency属性绑定到特定元素。有没有工作示例?它没有完全解决我的问题。这一个绑定ItemTemplate中的值。我需要绑定ch是在绑定到页面的ViewMoldel中定义的。如果它在项中,我可以不使用转换器直接绑定它。我添加了ViewModel示例以更好地说明它
<Page
x:Class="TempApp.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:converter="using:TempApp"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ListView x:Name="MyList">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
<Setter Property="Margin" Value="0,-1,0,0" />
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<Grid x:Name="ListItemDataTemplateGrid"
HorizontalAlignment="Stretch">
<Grid.Resources>
<converter:ValueToBackgroundConverter x:Key="ValueToBackgroundConverter" BackgroundColor="{Binding BgColor}" />
</Grid.Resources>
<Grid Background="{Binding Converter={StaticResource ValueToBackgroundConverter}}">
<!--Your Content-->
</Grid>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
public sealed partial class MainPage : Page
{
public List<TempList> ListDataSource = new List<TempList>();
public MainPage()
{
this.InitializeComponent();
FillList();
}
private void FillList()
{
ListDataSource.Clear();
ListDataSource.Add(new TempList { BgColor = "Red" });
ListDataSource.Add(new TempList { BgColor = "Red" });
MyList.ItemsSource = ListDataSource;
}
}
public class TempList
{
public string BgColor { get; set; }
}
class ValueToBackgroundConverter : DependencyObject, IValueConverter
{
public string BackgroundColor
{
get { return (string)GetValue(BackgroundColorProperty); }
set { SetValue(BackgroundColorProperty, value); }
}
public static readonly DependencyProperty BackgroundColorProperty =
DependencyProperty.Register("BackgroundColor",
typeof(string),
typeof(ValueToBackgroundConverter), null
);
public object Convert(object value, System.Type targetType, object parameter, string language)
{
//I've used static colors but you can do manipulations to convert string to color brush
if (BackgroundColor != null)
return new SolidColorBrush(Color.FromArgb(0xFF, 0xA3, 0xCE, 0xDC));
else
return new SolidColorBrush(Color.FromArgb(0xFF, 0xE3, 0xF0, 0xF4));
}
public object ConvertBack(object value, System.Type targetType, object parameter, string language)
{
throw new System.NotImplementedException();
}
}