【问题标题】:How to add custom property to user control for binding purposes?如何将自定义属性添加到用户控件以进行绑定?
【发布时间】:2014-08-11 21:53:37
【问题描述】:

我正在制作一个名为MusicalNotationBox 的用户控件来存储仅1 MusicalNotationMusicalNotationBox 必须绑定一个非空的MusicalNotation 对象)。我需要将 xaml (mvvm) 中的MusicalNotation 属性绑定到我的MusicalNotationBoxModelView 中的属性。

MusicalNotationBox 是一个 UserControl,用于可视化给定集合中的特定 MusicalNotation

所以,我希望能够这样做(我的 ModelView 为 DataContext,ofc)

<ItemsControl ItemsSource={Binding ListOfMusicalNotations}>
    <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Horizontal" IsItemsHost="True"/>
            </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemsTemplate>
        <DataTemplate>
            <c:MusicalNotationBox MusicalNotation={Binding MusicalNotation}/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

(添加 ItemsControl 标记以阐明我认为应该如何使用 &lt;MusicalNotationBox&gt; 的方式。)

如何做到这一点?


额外:

这是我的 MusicalNotationBox.XAML(以防万一)

<UserControl x:Class="NumberedMusicalScoresUserControl.MusicalNotationBox"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:NumberedMusicalScoresUserControl.MusicalNotationBoxProperties"
         mc:Ignorable="d">
<UserControl.Resources>
    <local:DotConverter x:Key="DotConverter"/>
    <local:NoteConverter x:Key="NoteConverter"/>
    <local:AccidentalConverter x:Key="AccidentalConverter"/>
    <local:BackgroundConverter x:Key="BackgroundConverter"/>
</UserControl.Resources>
<UserControl.InputBindings>
    <KeyBinding Key="OemPeriod" Command="{Binding KeyboardHotkeyCommand}" CommandParameter="Blank"/>
    <KeyBinding Key="D0" Command="{Binding KeyboardHotkeyCommand}" CommandParameter="Rest"/>
    <KeyBinding Key="D1" Command="{Binding KeyboardHotkeyCommand}" CommandParameter="N1"/>
    <KeyBinding Key="D2" Command="{Binding KeyboardHotkeyCommand}" CommandParameter="N2"/>
    <KeyBinding Key="D3" Command="{Binding KeyboardHotkeyCommand}" CommandParameter="N3"/>
    <KeyBinding Key="D4" Command="{Binding KeyboardHotkeyCommand}" CommandParameter="N4"/>
    <KeyBinding Key="D5" Command="{Binding KeyboardHotkeyCommand}" CommandParameter="N5"/>
    <KeyBinding Key="D6" Command="{Binding KeyboardHotkeyCommand}" CommandParameter="N6"/>
    <KeyBinding Key="D7" Command="{Binding KeyboardHotkeyCommand}" CommandParameter="N7"/>
    <KeyBinding Modifiers="Control" Key="P" Command="{Binding KeyboardHotkeyCommand}" CommandParameter="SHARP"/>
    <KeyBinding Modifiers="Control" Key="T" Command="{Binding KeyboardHotkeyCommand}" CommandParameter="FLAT"/>
    <KeyBinding Modifiers="Control" Key="OemPlus" Command="{Binding KeyboardHotkeyCommand}" CommandParameter="OCTAVE+"/>
    <KeyBinding Modifiers="Control" Key="OemMinus" Command="{Binding KeyboardHotkeyCommand}" CommandParameter="OCTAVE-"/>
    <KeyBinding Modifiers="Control" Key="OemPeriod" Command="{Binding KeyboardHotkeyCommand}" CommandParameter="DOT+"/>
    <KeyBinding Modifiers="Control" Key="OemComma" Command="{Binding KeyboardHotkeyCommand}" CommandParameter="DOT-"/>
</UserControl.InputBindings>

<Grid x:Name="grid" Margin="10,5,10,5"
      HorizontalAlignment="Center" VerticalAlignment="Center"
      Background="{Binding IsSelectedOrFocused, Converter={StaticResource BackgroundConverter}, Mode=OneWay}">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="Auto"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>

    <TextBlock Grid.Column="0" Grid.Row="1"
               Text="b"
               Visibility="{Binding Path=MusicalNotation.Accidental, Converter={StaticResource AccidentalConverter}, ConverterParameter=FL, Mode=OneWay}" 
               FontSize="15" FontFamily="CourierNew" 
               HorizontalAlignment="Center" VerticalAlignment="Center"/>
    <Path Grid.Column="1" Grid.Row="1" Stroke="Black" StrokeThickness="1" Stretch="Fill"
          Visibility="{Binding Path=MusicalNotation.Accidental, Converter={StaticResource AccidentalConverter}, ConverterParameter=SP, Mode=OneWay}" >
        <Path.Data>
            <LineGeometry StartPoint="1,0" EndPoint="0,1">
                <LineGeometry.Transform>
                    <RotateTransform CenterX="0" CenterY="0" Angle="30"/>
                </LineGeometry.Transform>
            </LineGeometry>
        </Path.Data>
    </Path>
    <TextBlock Grid.Column="1" Grid.Row="1" 
               Text="{Binding Path=MusicalNotation.Note, Converter={StaticResource NoteConverter}, Mode=OneWay}" 
               FontSize="15" FontFamily="CourierNew" 
               HorizontalAlignment="Center" VerticalAlignment="Center"
               Margin="2.5,0,2.5,0"/>
    <ItemsControl Grid.Column="1" Grid.Row="0" 
                  ItemsSource="{Binding Path=MusicalNotation.Octave, Converter={StaticResource DotConverter}, ConverterParameter=TOP, Mode=OneWay}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel IsItemsHost="True"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Ellipse HorizontalAlignment="Center" VerticalAlignment="Top"
                         Margin="{Binding Margin}" Fill="{Binding Fill}" 
                         Width="{Binding Diameter}" Height="{Binding Diameter}"/>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
    <ItemsControl Grid.Column="1" Grid.Row="2" 
                  ItemsSource="{Binding Path=MusicalNotation.Octave, Converter={StaticResource DotConverter}, ConverterParameter=BOT, Mode=OneWay}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel IsItemsHost="True"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Ellipse HorizontalAlignment="Center" VerticalAlignment="Bottom"
                         Margin="{Binding Margin}" Fill="{Binding Fill}" 
                         Width="{Binding Diameter}" Height="{Binding Diameter}"/>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
    <ItemsControl Grid.Column="2" Grid.Row="1" 
                  ItemsSource="{Binding Path=MusicalNotation.Dot, Converter={StaticResource DotConverter}, ConverterParameter=RIGHT, Mode=OneWay}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Horizontal" IsItemsHost="True"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Ellipse HorizontalAlignment="Left" VerticalAlignment="Center"
                         Margin="{Binding Margin}" Fill="{Binding Fill}" 
                         Width="{Binding Diameter}" Height="{Binding Diameter}"/>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Grid>

【问题讨论】:

    标签: c# wpf data-binding mvvm user-controls


    【解决方案1】:

    无需创建任何其他属性。您的控件仅由一个视图模型定义 - 只需使用 DataContextProperty(docs, example)。在您的情况下,它会自动为每个项目设置 - 这是 WPF 的行为。只需绑定到用户控件中所需的任何属性(其 dataContext 将由 WPF 引擎自动初始化)

    <ItemsControl ItemsSource="{Binding ListOfMusicalNotations}">
        <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal" IsItemsHost="True"/>
                </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemsTemplate>
            <DataTemplate>
                <c:MusicalNotationBox/>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
    

    如果您想了解如何添加属性,请阅读Add dependency property to control

    P.S.:实际上您可以将 MusicalNotationBox 定义为resources 中的模板而不是用户控件:

    <Resources>
            <DataTemplate x:Key="MusicalNotationBox">
                    <TextBox Text="{Binding Name}"/>
            </DataTemplate>
    </Resources>
    

    并像使用它

    <ItemsControl.ItemsTemplate>
        <StaticResource x:Key="MusicalNotationBox"/>
    </ItemsControl.ItemTemplate>
    

    【讨论】:

    • P.S:您是否阅读了我在上一个问题中链接到您的那些资源?它会给你很多见解。并尝试阅读有关 WPF 和 MVVM 的书籍或复杂教程。没有人可以知道一切,我同意。但即使一个接一个的提问,可以解决当前的一些具体问题,到头来也会给你留下很多知识的空缺。
    • 是的,我有。实际上它有点好,如果我可以做一些事情来向 XAML 添加“自定义”属性。我只是想知道这是否可能。每当我得到答案时,我什至会进一步研究,并尝试以我的方式进行创新。所以,不,我不是求助者。谢谢你提醒我。
    • 没有人有针对它的保险。这太诱人了。但最终是灾难性的。
    猜你喜欢
    • 1970-01-01
    • 2018-03-11
    • 1970-01-01
    • 1970-01-01
    • 2013-12-13
    • 2011-05-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多