【发布时间】:2021-09-29 11:53:16
【问题描述】:
我对 WPF 比较陌生,我正在尝试了解附加属性,以便在我用作学习基础的测试应用程序中使用它们。 AP 位于它自己的名为 AP.cs 的源文件中,该文件位于命名空间 WPFPages.ViewModels 中。
所以我创建了一个简单的 AP,如下所示,它存储了一个 int 值。
public class AP: DependencyObject
{
public static int Gettest ( DependencyObject obj )
{
return ( int ) obj . GetValue ( testProperty );
}
public static void Settest ( DependencyObject obj, int value )
{
obj . SetValue ( testProperty, value );
}
public static readonly DependencyProperty testProperty =
DependencyProperty . RegisterAttached ( "test", typeof ( int ), typeof ( AP ), new PropertyMetadata ( 2 ), Ontestchanged);
private static bool Ontestchanged ( object value )
{
Console . WriteLine ($"test value changed to {value}");
return true;
}
}
在我的 XAML 中,我使用 models:AP.test="21" 设置了值,该值按预期工作,由我在 AP 中的 WriteLine 调试验证。
但是,我希望将此值作为 ListBox 中的一列,因此有一个 DataTemplate 具有以下条目:
<TextBlock x:Name="tst"
Text="{Binding Path=(models:AP.test), RelativeSource={RelativeSource Self}}"
Width="55"/>
遗憾的是,我只在ListBox 中看到 AP 中的默认设置,而不是 21 的值。我已将其设置为我的 ListBox 属性。我已经在我的 XAML 文件中声明了命名空间,如下所示。
xmlns:models="clr-namespace:WPFPages.ViewModels"
我已经阅读了有关附加属性的所有可能的文章,并在语法方面尝试了主题的更多变体以使其工作,但根本没有成功。到目前为止,我已经花了 3 天时间试图让这个简单的 AP 工作。
由于我对 Binding 的复杂性缺乏经验,我确信这很简单,但非常感谢一些帮助,以了解我如何完成这项工作,因为我可以看到 AP 的强大功能,如果我能让它们正常工作就好了?
更新而不是使用评论:
<ListBox x:Name="listboxclass"
ItemContainerStyle="{StaticResource lvItemStyle1}"
BorderThickness="2"
BorderBrush="{StaticResource Blue0}"
FontWeight="Normal"
FontSize="14" Margin="0,0,0,164" >
<ListBoxItem
Height="45"
models:AP.test="21"/>
相关Style代码为:
希望这可以澄清它。我很高兴现在选择的列中出现了相同的值。
<Style x:Key="lvItemStyle1" TargetType="{x:Type ListBoxItem}">
<!--<Setter Property="Background" Value="{Binding (models:AP.Background)}"/>-->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Grid>
<!--<Border x:Name="Bd"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}"
SnapsToDevicePixels="true">
<Border.Background>
<SolidColorBrush x:Name="borderbckgrnd" Color="{TemplateBinding models:AP.Background}" />
</Border.Background>
<ContentPresenter x:Name="contentpresenter"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
</ContentPresenter>
</Border>-->
<!--I have tried ALL of these & they ALL cause Exceptions on loading
"{Binding models:AP.test}"
"{Binding Path=(models:AP.test)}"
"{Binding (models:AP.test)}"
"{Binding Source=models:AP.test}"
"{TemplateBinding models:AP.test}"-->
<Border x:Name="Bd" >
<StackPanel Orientation="Horizontal" >
<TextBlock Text="{Binding CustomerId}"
Height="{Binding ActualHeight, ElementName=NwCustomerDataTemplateBorder1}"
Width="50"
Padding="1"
x:Name="CustomerId"/>
<!--NB Output window shows :
AP : test value changed to 2
AP : test value changed to 21
so it is definitely being set.
but the field is empty in the list when run-->
<TextBlock x:Name="tst"
Text="{Binding Path=models:Attach.test}"
Foreground="Red"
Width="55"/>
<!--this does not give error, but does not work either
Height="{Binding Path=models:AP.test, RelativeSource={RelativeSource Self}}"-->
<TextBlock Text="{Binding CompanyName}" Width="165" Padding="1" x:Name="CompanyName"/>
<TextBlock Text="{Binding ContactName}" Width="135" Padding="1" x:Name="ContactName"/>
<TextBlock Text="{Binding ContactTitle}" Width="40" Padding="1" x:Name="ContactTitle"/>
<TextBlock Text="{Binding Address}" Width="150" Padding="1" x:Name="Address"/>
<TextBlock Text="{Binding City }" Width="80" Padding="1" x:Name="City"/>
<TextBlock Text="{Binding PostalCode}" Width="75" Padding="1" x:Name="PostalCode"/>
<TextBlock Text="{Binding Country}" Width="75" Padding="1" x:Name="Country"/>
<TextBlock Text="{Binding Phone}" Width="95" Padding="1" x:Name="Phone"/>
<TextBlock Text="{Binding Fax}" Width="95" Padding="1" x:Name="Fax"/>
</StackPanel>
</Border>
<!-- ... -->
【问题讨论】:
-
你在哪个元素上设置了
models:AP.test="21"?应该为每个列表框项设置不同的值还是对所有项设置相同的值?您写道您想要在ListBox中添加一个列,那么您是否使用了GridView或者您的意思是什么? -
请注意,仅声明附加属性的类不需要从 DependencyObject 派生。该类中的所有声明都是静态的。
-
RelativeSource={RelativeSource Self}表示您将在 DataTemplate 中名为tst的 TextBlock 上设置附加属性。你是怎么做到的? -
澄清一下,我的列表框声明是:-
-
糟糕
标签: c# wpf xaml data-binding attached-properties