จะตรวจสอบกล่องรายการ (MVVM) ได้อย่างไร

ฉันหวังว่าฉันจะสามารถอธิบายรหัสและปัญหาของฉันได้ถูกต้อง เนื่องจากมีรหัสจำนวนมาก เรากำลังสร้างแอปพลิเคชัน Book Manager ใน Visual Studio โมเดล (Book.cs) มีคุณสมบัติของหนังสือ (ผู้แต่ง ชื่อเรื่อง หนังสือวางจำหน่าย ฯลฯ)

ใน MainWindow.xaml เรามีกล่องรายการที่มีหนังสือทั้งหมดอยู่ในรายการ และทางด้านซ้ายจะมีป้ายกำกับและกล่องข้อความที่สอดคล้องกับคุณสมบัติ (ป้ายกำกับ "ผู้เขียน" และในกล่องข้อความจะปรากฏชื่อผู้เขียน) ด้วยกล่องข้อความนี้ คุณสามารถอัปเดตคุณสมบัติได้ xaml มีลักษณะเช่นนี้:

<Window x:Class="BookApplication.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:model="clr-namespace:BookApplication.Model"
        xmlns:viewModel="clr-namespace:BookApplication.ViewModel"
        mc:Ignorable="d"
        Title="Book-Manager" Height="350" Width="525">
    <Window.Resources>
        <model:Book x:Key="myBook" Title="Harry Potter und die Heiligtümer des Todes" Author="J.K.Rowling" Publisher="Carlsen" Edition="1" Release="01.01.2017" ></model:Book>
        <viewModel:BookCollectionViewModel x:Key="bcvm"></viewModel:BookCollectionViewModel>

    </Window.Resources>


    <DockPanel>
        <Menu DockPanel.Dock="Top">
            <MenuItem Header="Datei">
                <MenuItem Header="Neu" Command="{Binding NewClick, Mode=OneWay, Source={StaticResource bcvm}}" InputGestureText="Strg+N"/>
                <Separator/>
                <MenuItem x:Name="Open" Header="Öffnen" Command="{Binding LoadClick, Mode=OneWay, Source={StaticResource bcvm}}" InputGestureText="Strg+O"/>
                <MenuItem x:Name="Save" Header="Speichern" Command="{Binding SaveClick, Mode=OneWay, Source={StaticResource bcvm}}" InputGestureText="Strg+S"/>
                <MenuItem Header="Speichern unter..." Command="{Binding SaveAsClick, Mode=OneWay, Source={StaticResource bcvm}}"/>

            </MenuItem>
            <MenuItem Header="Neues Buch" Command="{Binding NewBookClick, Mode=OneWay, Source={StaticResource bcvm}}"></MenuItem>
        </Menu>


        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="252*"/>
                <ColumnDefinition Width="265*"/>
            </Grid.ColumnDefinitions>

            <Grid Grid.Column="0" Margin="-2,0,0,0">
                <Label x:Name="labelTitle" Content="Titel" HorizontalAlignment="Left" Margin="9,10,0,0" VerticalAlignment="Top" Width="46" Height="20" FontSize="8"/>
                <TextBox x:Name="textboxTitle" HorizontalAlignment="Left" Height="20" Margin="87,10,0,0" TextWrapping="Wrap" Text="{Binding ElementName= BooksListBox, Path=SelectedItem.Title}" VerticalAlignment="Top" Width="160" FontSize="8" />

                <Label x:Name="labelAuthor" Content="Autor" HorizontalAlignment="Left" Margin="10,30,0,0" VerticalAlignment="Top" Width="62" Height="22" FontSize="8"/>
                <TextBox x:Name="textboxAuthor" HorizontalAlignment="Left" Height="18" Margin="87,34,0,0" TextWrapping="Wrap"  Text="{Binding ElementName=BooksListBox, Path=SelectedItem.Author}" VerticalAlignment="Top" Width="160" FontSize="8" />

                <Label x:Name="labelPublisher" Content="Verlag" HorizontalAlignment="Left" Margin="10,52,0,0" VerticalAlignment="Top" Width="45" FontSize="8" Height="24"/>
                <TextBox x:Name="textboxPublisher" HorizontalAlignment="Left" Height="17" Margin="87,58,0,0" TextWrapping="Wrap" Text="{Binding Source={StaticResource myBook}, Path=Publisher, Mode=TwoWay}" VerticalAlignment="Top" Width="160" FontSize="8" />

                <Label x:Name="labelEdition" Content="Auflage" HorizontalAlignment="Left" Margin="10,76,0,0" VerticalAlignment="Top" Width="45" FontSize="8" Height="26"/>
                <TextBox x:Name="textboxEdition" HorizontalAlignment="Left" Height="15" Margin="87,79,0,0" TextWrapping="Wrap" Text="{Binding ElementName=BooksListBox, Path=SelectedItem.Edition}" VerticalAlignment="Top" Width="160" FontSize="8" />

                <Label x:Name="labelRelease" Content="Veröffentlichung" HorizontalAlignment="Left" Margin="9,99,0,0" VerticalAlignment="Top" Width="102" FontSize="8"/>
                <TextBox x:Name="textboxRelease" HorizontalAlignment="Left" Height="14" Margin="87,103,0,0" TextWrapping="Wrap" Text="{Binding ElementName=BooksListBox, Path=SelectedItem.Release, Mode=TwoWay}" VerticalAlignment="Top" Width="160" FontSize="8" />

                <Label x:Name="labelISBN" Content="ISBN" HorizontalAlignment="Left" Margin="9,120,0,0" VerticalAlignment="Top" Width="81" FontSize="8"/>
                <TextBox x:Name="textboxISBN" HorizontalAlignment="Left" Height="14" Margin="87,125,0,0" TextWrapping="Wrap" Text="{Binding ElementName=BooksListBox, Path=SelectedItem.Isbn}" VerticalAlignment="Top" Width="160" FontSize="8" />

                <Button x:Name="buttonRemove" Command="{Binding RemoveBookClick, Mode=OneWay, Source={StaticResource bcvm}}" Content="Löschen" HorizontalAlignment="Left" Margin="9,160,0,0" VerticalAlignment="Top" Width="75"/>
            </Grid>

            <ListBox Grid.Column="1" x:Name="BooksListBox" ItemsSource="{Binding Source={StaticResource bcvm}}" SelectedItem="{Binding Source={StaticResource bcvm}, Path=SelectedBook}">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel>
                            <TextBlock FontWeight="Bold" FontSize="12" Text="{Binding Path=Title}"/>
                            <StackPanel Orientation="Horizontal">
                                <TextBlock Text="{Binding Path=Author}"></TextBlock>
                                <TextBlock Text=";  Auflage: "></TextBlock>
                                <TextBlock Text="{Binding Path=Edition}"></TextBlock>
                            </StackPanel>
                            <Canvas Width="50" Height="12" HorizontalAlignment="Left" >
                                <Ellipse Name="LeftEllipse" Height="10" Stroke="Black" Fill="{Binding Path=ColorLeft}" Width="10" Canvas.Left="10"/>
                                <Ellipse Name="MiddleEllipse" Height="10" Stroke="Black" Fill="{Binding Path=ColorMiddle}" Width="10" Canvas.Left="30"/>
                                <Ellipse Name="RightEllipse" Height="10" Stroke="Black" Fill="{Binding Path=ColorRight}" Width="10" Canvas.Left="50"/>
                            </Canvas>
                        </StackPanel>

                    </DataTemplate>
                </ListBox.ItemTemplate>

            </ListBox>

        </Grid>
    </DockPanel>

</Window>

หากคุณคลิกที่หนังสือเล่มใด ๆ ในรายการ ค่าของคุณสมบัติจะอยู่ในกล่องข้อความด้านซ้าย และค่าเหล่านี้คุณสามารถแก้ไขได้ดังที่ฉันบอกไปแล้ว

ตอนนี้ฉันต้องทำการตรวจสอบ ปัญหาคือ ฉันสามารถค้นหาได้เฉพาะการตรวจสอบคุณสมบัติโดยตรงเท่านั้น และฉันต้องการตรวจสอบค่าและค่าที่อัปเดตของกล่องรายการ

ฉันพยายามทำสิ่งนี้ (ที่มา: https://msdn.microsoft.com/es-es/library/ms753962 แหล่งที่มาไม่ใช่ภาษาอังกฤษ แต่โค้ดค่อนข้างชัดเจน)

ฉันสร้างคลาส AuthorRule ที่มีลักษณะดังนี้:

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;

namespace BookApplication.Model.Validation
{
    class AuthorRule : ValidationRule
    {
        public AuthorRule()
        {

        }

        public override ValidationResult Validate(object value, CultureInfo cultureInfo)
        {

           if (String.IsNullOrWhiteSpace((String)value))
           {
                return new ValidationResult(false, "Dieser Feld ist verpflichtend.");
            }
            else
            {
                return new ValidationResult(true, null);
            }

        }
    }
}

เพียงเพื่อพิสูจน์ว่าสนามว่างเปล่า โมเดลหรือ Book.cs ของฉันไม่มีการเปลี่ยนแปลง MainWindow.xaml ของฉันมีลักษณะเช่นนี้ (มันเหมือนกับโค้ดอีกชิ้นหนึ่ง แต่ฉันจะแสดงการเปลี่ยนแปลงใน WindowResources และในกล่องข้อความ "ผู้เขียน"):

<Window.Resources>
        <model:Book x:Key="myBook" Title="Harry Potter und die Heiligtümer des Todes" Author="J.K.Rowling" Publisher="Carlsen" Edition="1" Release="01.01.2017" ></model:Book>
        <viewModel:BookCollectionViewModel x:Key="bcvm"></viewModel:BookCollectionViewModel>

        <ControlTemplate x:Key="validationTemplate">
            <DockPanel>
                <TextBlock Foreground="Red" FontSize="20">
                    <Run Text="!" />
                </TextBlock>
            </DockPanel>
        </ControlTemplate>

        <Style x:Key="textBoxInError" TargetType="{x:Type TextBox}">
            <Style.Triggers>
                <Trigger Property="Validation.HasError" Value="true">
                    <Setter Property="ToolTip" Value="{Binding (Validation.Errors)[0].ErrorContent, RelativeSource={x:Static RelativeSource.Self}}" />
                </Trigger>
            </Style.Triggers>

        </Style>

    </Window.Resources>

ป้อนคำอธิบายรูปภาพที่นี่

รูปภาพด้านบนเป็นภาพหน้าจอของกล่องข้อความ "ผู้เขียน" ฉันไม่รู้ว่าเส้นทางและแหล่งที่มาควรเป็นอย่างไร ดังนั้นกล่องรายการจึงยังคงเชื่อมต่ออยู่!!

ฉันขอโทษสำหรับคำถามยาว ใครสามารถช่วยฉันได้บ้าง


person bonishadelnorte    schedule 18.01.2018    source แหล่งที่มา


คำตอบ (1)


คุณได้ตั้งค่าคุณสมบัติข้อความในบรรทัดแรกแล้ว และคุณกำลังตั้งค่ากลับในโหนด TextBox.Text อีกครั้ง คุณอาจต้องลบแอตทริบิวต์ Text ออกและเป็นค่าของมันตั้งแต่แรก นอกจากนี้ ไม่จำเป็นต้องระบุฟิลด์แหล่งที่มา วิธีแก้ปัญหาสุดท้ายสำหรับกล่องข้อความควรเป็นดังนี้

<TextBox x:Name="textboxAuthor" HorizontalAlignment="Left" Height="18" Margin="87,34,0,0" TextWrapping="Wrap"  VerticalAlignment="Top" Width="160" FontSize="8" Validation.ErrorTemplate="{StaticResource validationTemplate}" Style="{StaticResource textBoxInError}">
                    <TextBox.Text>
                        <Binding Path="SelectedItem.Author" ElementName="BooksListBox" UpdateSourceTrigger="PropertyChanged">
                            <Binding.ValidationRules>
                                <validation:AuthorRule/>
                            </Binding.ValidationRules>
                        </Binding>
                    </TextBox.Text>
                </TextBox>

สิ่งนี้ควรจะได้ผล

person Rajesh Gupta    schedule 18.01.2018